OmniAICreator/Qiita-1.07M huggingface dataset:
Excelの簡易パスワード生成

Excelでのパスワード生成，あちこちにありそうなネタですが…
よくあるのは，使いたい文字種を列挙しておいて，
その長さの範囲内の乱数を生成して1文字をランダムに取り出し，
それを欲しい文字数分だけ並べる，というやつですね．
これは，セル内の数式がやたら長くはなりますが，最初の入力はコピペでよいし，
一度生成すれば単にコピペするだけなので割と最強な気もします．

とはいえ，ちょこっとやりたいときにもうちょっとお手軽な，というので，こういうのも時々使ってます．

```vba
=BASE(RANDBETWEEN(0,36^8-1),36,8)
```

これだと英字は大文字だけになりますけど(BASE関数で指定できる基数は36まで)，元文字列を延々と打つのもたるいと思ってしまう無精者なので…

生成されるパスワード文字列の例は以下のようになります．

| Password | 
|:---------|
| 87LTG7ZW |
| PD45C9MP |
| WG78QM4Y |

要は，乱数を生成させ，0,1,..9,A,B,...,Z の36進数として表しているだけです．

ちなみにExcelは10進数で$ 10^{15}$までしか保持していないので，
$ \log_{36} 10^{15}$ $ \sim 9.64 $ということで，9桁までですね．
10桁以上は & で同じ処理を連結する，というのはよくある手法と一緒です．
AWS 用語解説！(EC2,EBS,Route53,RDS,S3)

##AWSの専門用語が多い件
私は現在、AWSにポートフォリオをデプロイしようとしているエンジニア志望の者なのですが、AWSを触ってみた所感として、VPCとかEC２とか略語が多すぎて理解しづらい。そしてudemyで講座を受けても、すぐに忘れてしまうので一度、主要な機能の略語を整理して把握しておきたいと思いまました。(AWSはサービスの種類が豊富で書ききれないため)

エンジニア初心者なので間違いがあれば指摘していただけると幸いです。

##AWSとは？
ちなみにAWSはAmazon Web Serviceの略でAmazonが提供するクラウド型Webサービスの総称のことです。
モール型ECサイトで有名なAmazonですが、AWSもAmazonの収益の柱の一つで、CEOのジェフ・ベゾスは将来の主力事業として見ているそうです。

##EC2
EC2は「Elastic Compute Cloud」の略称で、AWSに仮想サーバを作るサービスのことです。AWSでデプロイ（インターネットにサービスを公開する）する場合は必ず使います。そして立てたサーバのそれぞれをインスタンスと言います。
昔はサイトを作るときに仮想サーバというのものが無かったので、自社サーバ（ハードウェア）を会社に設置していて、サイトの訪問者数などが増え、サーバの負担が大きくなると、より容量の多いサーバを設置するというのを繰り返していたそうです。しかし、この仮想サーバという概念が出てきてからは容量が大きくなったらクラウド上にあるサーバの容量を大きくするだけで済む様になったのです。

##EBS
EBSは「Elastic Block Store」の略称で、↑のEC2とはセットで使います。EC2で立てたサーバを停止させるとデータが消えてしまうため、サーバを停止させてもデータを消えない様にするというのが仕事です。

##Route53
Routes53はサービスのドメインを登録、管理、運用することができるドメイン登録機能、DNS（URLとIPアドレスの照合を行うサーバ）ルーティング機能、DNSヘルスチェック機能が付いています。


##RDS
RDSは「Relational Database Service」の略称で、マネージド型DBです。
マネージドというのはAWSがDBの運用をしてくれるという意味で使われています。
そしてRDSにはマルチAZ配置という複数のアベイラビリティーゾーン（東京とか、オハイオとか、シンガポールとか）に置けることで災害などのトラブルが起きてもサービスの停止のリスクを抑えることができます。


##S3
S3とは「Simple Storage Service」の略称で、容量無制限でデータを保存してくれるサービスです。EBSでもデータを保存できるのですが、S３の方が大量のデータを安く保存してくれます。

##まとめ
今回はAWSを触ることになったら、とりあえず覚えておくべき機能を厳選し、まとめました。今回の記事が初心者エンジニアさんのAWSの理解につながったら嬉しいです。
2021 秋版 Ubuntu + AMD GPU で amdgpu ドライバインストールし powerlimit するメモ

## 背景

来年あたりメタバース関連で RDNA2 or later AMD GPU で GPU レイトレクラスタを構築する必要が出てきた(来年になったら Vulkan raytrace がまともに使えそうになりそう + AMD GPU はデータセンターで動かしても OK)

とりあえずはマイニングして稼いだり, Vulkan 周り環境整備しておきたい

## AMD GPU のよいところ

* powerlimit がユーザー権限で行える(正確には `render` グループ?)
* データセンターで動かしても OK(EULA で制限なし. また OSS stack ならそもそも EULA 不必要)
* X11 入れなくても細かいクロック制御とファンコントロールできる(はず. 未検証)

## 環境

* amdgpu 21.40(2021/11/11 release)
* Ubuntu 20.04.03 or latewr
* GPU は RDNA2 or later(post VEGA)を想定します.
  * OpenCL は `rocr`(OSS 版). Polaris だと OpenCL のスタックが異る(proprietary しかない? ため)
* マイニングや Vulkan の利用を想定(OpenGL は使わない)


カーネルは HWE 5.11 系ではどうも不調になりやすい(デバイスが認識されない, 負荷がかかるとリセットされる)ようです. 5.8 (2022/01 時点での LTS generic(non-hwe)?)にしておいたほうがよいでしょう(新し目のマザーボードだと 2.5 GbE など 5.11 でないといろいろ認識されないものがでてくるかもなので, マザーボードはそこそこ古いのが理想).
      
## driver

最近は AMD も SW 周りに裂ける予算が多くなったのか, ドライバスタックもこなれてきたのか, 昨年の Navi(RX5700)の頃に比べると Linux のドライバまともになってきた感があります.
21.40 から, nvidia ドライバのように network install が基本になりました.

https://www.amd.com/ja/support

のサイトから落とせるのはメタパッケージになります.

apt で入れた後,

```
$ amdgpu-install
```

で一式入ります. デフォルトでは OSS 版(rocm opencl)が入ります.

https://amdgpu-install.readthedocs.io/en/latest/

Ubuntu 20.04 の場合は `render` と `video` グループに登録が必要になります.


## powerlimit

grub に 

`amdgpu.ppfeaturemask=0xffffffff` を入れます.


https://unix.stackexchange.com/questions/620072/reduce-amd-gpu-wattage

`/sys` ファイルシステム経由でいろいろ設定できるようですが, めんどいんでとりあえずは rocm-smi でやります.

amdgpu-install あたりで入る rocm 関連には rocm-smi は入っていないので, 自前でビルドします.

```
$ git clone https://github.com/RadeonOpenCompute/rocm_smi_lib
$ cd rocm_smi_lib
$ mkdir build
$ cd build
$ cmake -DCMAKE_INSTALL_PREFIX=`pwd`/../dist ..
$ make && make install
```

これで `rocm_smi_lib/dist` に rocm-smi 関連入ります.
引数なしに動かすと 

```
 rsmi_status_t get_frequencies(amd::smi::DevInfoTypes, uint32_t, rsmi_frequencies_t*, uint32_t*): Assertion `f->frequency[i-1] <= f->frequency[i]' failed.
Aborted (core dumped)
```

などと落ちますが, 一応 powerlimit は大丈夫っぽそうです.

```
$ rocm-smi --setpoweroverdrive 100
```

複数 GPU ある場合は `-d N` で指定.

利用ワットを見る場合は

```
$ rocm-smi --showpower  # or rocm-smi -P
```


とりあえず 100W に powerlimit で RX6800(RDNA2)で teamredminer で 56 MH/s @ 110W でました :smile: 
HiveOS とかで動かすのに比べれば効率やや低いかもですが, まあ十分でしょう.

## Vulkan ray tracing.

OSS 版はレイトレ関連まだありません.
Vulkan pro 版(proprietary 版)だといけるっぽい.

Mesa(AMDVLK) もうすぐかしらん?
【javascript】コンストラクタ関数

# 目的
javascriptの備忘録。

# コンストラクタ関数とは
新しくオブジェクトを作成するための雛形となる関数。
コントラクタ関数（雛形）を作ることで同じ関数を複数作る必要がなくなる。

# 使い方

newを先頭につけてコンストラクタ関数を実行する。

```js
const obj = new A();

```
* newで作成したオブジェクトを「インスタンス」という。
* newでオブジェクトを作成することを「インスタンス化」という。

###  コンストラクタ関数を作成する。

1. コンストラクタ関数と通常の関数との定義の違い。
    1. 関数名の先頭の文字を大文字にする。person => Person

```js
function Person(name, age){ 
    this.name = name; //引数をthisに渡すことでthisが使えるようになる。
    this.age = age;
}

const bob = new Person('Bob', 18);
const tom = new Person('Tom', 21);
```
AWS Quicksightの整数表示制限

TLDR: QuickSightの仕様で整数を表示するとき、長くなりそうなものは文字型に変えよう

###修正する前に表示されたデータ
![スクリーンショット 2021-11-17 16.40.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546130/5b8a3c0a-0810-1cd4-51ab-bddf1ecba7aa.png)



###修正後に表示するデータ
![スクリーンショット 2021-11-17 16.40.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546130/08e1fc8f-0afb-3d8d-6883-a457f331eea3.png)

SQLで以下のように文字型に変換すればおk

```
select
{column名}::varchar
from
{table名}
```

https://docs.aws.amazon.com/quicksight/latest/user/supported-data-types-and-values.html

上記のDocumentから、Quicksightの整数表示は9007199254740991 （何故かJavascriptのMAX_SAFE_INTEGER)までです、それ以上を超えると正しく表示されない可能性があります。
IFTTTで業務改善　移動車両の発着時間を自動記録する

## 移動販売とは

　私はとあるスーパーで、移動販売や無人店舗の新規開拓を担当しています。
　
　地方では人口減少を背景に、コンビニや個人商店が閉店する事例が増え、
　身近な買物場所を失う方が、年々増えているそうです。
　高齢の方の、体力低下・免許返納も相まって、買物難民は増加の一途を辿っています。

　そんな中、**ご自宅前まで伺い、商品を販売する「移動販売」が好評**を頂いています。
　車にぎっしり詰まった商品の中から、欲しいもの選び、自分でお会計する。
　<font color="Red">**通販ではなく「自分で商品を見て選び　自分で買いたい」**</font>と話すお客さまはとても多い。
　![123.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1793443/d579a59a-b86d-2d2e-f7d9-6f7bbd669e79.png)
　便利さの裏側で、運行ルートの策定には、いつも運営側の悩みの種です。
　近い順番に回ると効率的ですが、「月曜日は夕方家にいない」などニーズは多種多様です。　
## どの地点に何時に行くか

　地域のお客さまからは毎日のように「〇〇の家の前も来て!」と新たなご要望を頂きますが、
　そのすべてに対応するわけにはいきません。
　
　販売車両は、1日6～8時間の移動時間の内、どこの地点をどのタイミングで回ればよいか
　<font color="Red">**どのようなルートにすれば、新たな販売拠点を増やせるか、常に実験・検証**</font>しています。

　分析の一環として　<font color="Red">**毎日手書きの「運行日報」**</font>を付け、
　**①どの地点に　　②いつ到着して　　③何分間販売して出発したのか** を毎日記録。

　しかし**販売は一分一秒を争い**ます。
　ポイント着くと何人ものお客さまが**「早く商品見せて～！！」と大盛況。**
　ずっと販売していたいですが、次のポイントの予定時刻に間に合わせるために
　**「ごめん、もう次の場所にいくらから今日は終わるね」と泣く泣く店じまい。**

　そんな中、<font color="Red">**地点・到着時間・出発時間を毎回手書きで書く時間はもったいない。**</font>
　今回はこの<font color="Red">**作業の一部を自動化**</font>することにしてみました。
![収支絵.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1793443/168f324d-ec5e-8bf6-d00a-776aed7f43d0.png)


## 登録地点に入った時・出た時の記録がLINE上で残る

　IFTTTを使い、<font color="Red">**あらかじめ登録された地点に入った時・出た時がLINEで残る**</font>よう設定。
　位置情報取得・LINE通知まで、スマホを一切触らず、全自動完結させることができました。
![ifttt.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1793443/ba7562af-ef02-d59e-27fb-db2bc6360e35.png)

　LINE側は、現在のマップイメージ図などを自動送信してくれる機能もありましたが、
　毎日　①地点名②時間　が分かればいいだけなので、シンプルな構成にしました。

![トリガー.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1793443/76d0e981-bfbf-6784-1ba5-22b325f578b4.png)

## 現場のドライバー・管理者に紹介してみました

**<ドライバー>**

　地点ごとに「〇〇頃時に行きます」とあらかじめ伝えてあり、<font color="Red">**絶対に遅れる訳に行かず、**</font>
<font color="Red">**　緊張感とバタバタがものすごいので「手書き箇所がちょっとでも減る」はとても嬉しい。**</font>

　特に地点に入った時、もうすでに「早く買物させて～」とお客さまが待ってくれている。
　雨の日などは特に<font color="Red">**1秒でも早く商品を見せてあげたい**</font>ので、手書きが減ると嬉しい。

　販売中は本当に忙しいので、将来的にお店の総務担当者さんもグループに入れて、
　自分以外の人が記録してくれるようになれば嬉しい。だめかな？(笑)
　
**<現場管理者社員>**　複数のドライバーをマネジメント　ルート改廃も担当

　ほんの一部の人だが、販売日報に嘘を書き、実際はさぼっていた事例があるので、
　手書から楽になるだけではく、<font color="Red">**ドライバーへの程よい緊張感も生まれる**</font>と思う。

　早く全地点登録してほしい。(IFTTT無料枠では5つまでしかできない)

　ドライバーには一か所でも多く回り、一秒でも長く販売してほしいので、今回を皮切りに
　<font color="Red">**日報のその他の項目**</font>も自動、手書きではない方法に切り替えてほしい。

　<font color="Red">**日報以外でも「お客さまからの注文」**</font>もすべて手書きで受け付けている。
　ここを<font color="Red">**自動化・もしくはLINEなどで簡単に受け付け**</font>られるようにしてほしい。


　こちらの記事なども参考に、更なる自動化に向け、技術実装してきたいと思っています。

　参考：[健康管理チェックをExcelからGoogleフォームとGmailで毎日チェック通知できる機能](https://qiita.com/yudiramaruyama/items/29610752e6db7d217cd8)

　その他参考にした記事一覧はこちら
　最後まで読んでくれてありがとう!!

https://zenn.dev/okinaka/scraps/9d2429c6dbdae0
nRF Connect SDK:カスタムデバイスの追加

#カスタムデバイスの追加
nRF Connect SDK(以下NCS)自体もかなりいろんなデバイスをSDK側でサポートしています。例えばICM-42605なんて比較的新しいIMUセンサーもサポートしていたりしてちょっとビックリです。
ところが現実問題としてデバイスは世の中に山のようにあるわけで、NCSがサポートしているデバイスだけで作れるはずはありません。サポートしていないデバイスは自分で追加する必要があります。
#とここまで書いて
結論を言いますと**諦めました**。
とてもじゃないですが、カスタムデバイスを追加する手間と効果を考えると全然割に合いません。割に合うとか合わないとかの話じゃねーんだよ、と言いたいところなのですがあえて言います。割に合いません。
ちなみにメリットとしてはCPUを変更してもソースコードを一切いじる必要がない、というところなのですが、マルチCPUで作ることって今の時代あるんですかね・・・？
#直接APIを叩くのでも問題はなさそう
ちなみに私の記事としてはAPIを直接叩く方式のやり方を先に公開しています。もちろんHALを使用する方法はその時から認識していますが、ここにきてようやく手を付けようと思って調べた矢先の話です。メチャクチャめんどくさい、と(笑)。
で、このスレッドを見つけてちょっと気が楽になったんですよね。

https://devzone.nordicsemi.com/f/nordic-q-a/70627/what-s-the-official-way-to-implement-a-simple-peripheral-spi-i2c-etc-with-ncs

DeepLで翻訳したものを引用します。
>私の知る限り、Zephyr APIは、https://github.com/zephyrproject-rtos/zephyr/blob/master/drivers/spi/spi_nrfx_spim.c などに見られるように、nrfx HALを使用しています。これらの関数(他のドライバも同様)は、Zephyrドライバのapi->dostuff()関数の呼び出しから一度だけ呼び出されます。

>私の理解が正しければ、Kconfigでperihperalsを有効にすると、Zephyr APIから呼び出される基本的なドライバを選択することになります。Zephyr APIを使うと、将来MCUを変更したときにプロジェクトの移植が容易になると思います。

>私自身は、コードの一貫性を保つために、できるだけZephyr APIを使用するようにしています。欠点としては、Zephyrの設定で何が起こっているのか、100%明確ではないことです。

>しかし、私もあなたと同じように、nrfxの機能をZephyrの機能ではなく直接使用している人をDevzoneで見たことがあるので、nordicではどの方法が「正しい」のか疑問に思っています。これは利便性と制御性の問題だと思います。

>この件について、Nordicの担当者から正式な回答があるといいのですが。今後、NCSはZephyrとの差別化を図っていくのでしょうか？

>www.DeepL.com/Translator（無料版）で翻訳しました。

おそらくここで出てくる直接叩いている人たち、というのは明らかに効率を追求したものだと思います。だって直接アクセスしたほうがはるかに簡単で早いですもの。
#結論
この記事自体は何か技術的に参考になるわけではないです。強いて言うなら、こんなクソめんどくさいこと誰がやるんだ・・・と疑問に思ったときに、世の中には他にも同じようにめんどくさくて諦めたという人がいるんだ、やっぱり俺は正しかった！ということを知ることができる、くらいですね(笑)。
ReactNativeとExpoでスマホアプリ開発〜開発環境構築〜

# Expoにアカウントを作成する

https://expo.dev/

# PC側の準備
実際に試した環境

- Ubuntu18.04
- node: 14.15.4

## expo-cliをインストール

```
npm install -g expo-cli@4.13.0
```

## Expoにログインする

```
expo login
```
で、https://expo.dev/ に登録したIDとPassでログインする。


# iphoneとandroidの仮想的な画面で確認するためのツールの準備
## iphoneはXcodeをインストール
シミュレータの立ち上げ方は、Xcode→Open Developer Tool→Simulator。
下記のような仮想的なiphoneが立ち上がる。

![スクリーンショット 2021-11-17 14.18.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2284107/24298a8c-a9e7-c5c4-5f72-d93b01785c7e.png)

## AndroidはAndroid Studioをインストール
まだ試していない。

# スマホ側の準備
expo clientのアプリをスマホにインストールしておくと、実機でアプリを確認することができる。
各ストアで手に入る。
![スクリーンショット 2021-11-17 16.17.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2284107/4e3caf9f-bbbf-484c-8b43-1b74ecd7d4a4.png)


## iPhoneなら「Expo Go」

## Androidなら「Expo」
https://play.google.com/store/apps/details?id=host.exp.exponent&hl=ja&gl=US
Goのデバッグ方法

#ステップ

###1ターミナルを見る

###2ファイル名と行が書かれているのでその箇所を検索してその該当箇所にいく

###3fmt.Printf("%v", 表示させたいもの)をする

#本番環境では出来てローカルでは出来ない理由

コードは同じはずなので環境変数の問題かな
【2021年11月25日版】Azure Machine Learning の利用料金について

#はじめに
Azure、AWSをはじめ、多くのパブリッククラウドでは様々なマネージドサービスが用意されており大変便利ですよね。
でも、簡単に始めてみたら月末に想像以上の請求がきちゃった。。。
なんてことはよくあるんじゃないでしょうか？

今回はAzure Machine Learning を利用する上で気をつけたいサブリソース料金についてお話します。

#Azure Machine Learning とは？
Azure Machine Learning とはMicrosoft Azure で提供されている、機械学習が簡単に始められるサービスです。
ポータル上からワークスペースを立ち上げれば、機械学習環境を構築するためのあれこれを自動で実施してくれます。

#利用料金について
Azure Machine Learning ワークスペース自体には課金は発生いたしません。
ワークスペース内に作成したコンピューティング、サブリソース料金に対して料金が発生します。

#コンピューティング料金
ワークスペース内のリソースの中で課金ウェイトの多くを占めるのがコンピューティングです。

■コンピューティング（STANDARD_DS3_V2）
時間：約 46.511 円
月額：46.511 [円/時間] x 24 [時間/日] x 31 [日] = 34,604.184 円
[コンピューティング料金](https://azure.microsoft.com/ja-jp/pricing/details/machine-learning/)

#サブリソース料金
ワークスペース内でコンピューティングを立ち上げると以下のサブリソース料金が発生します。
コンピューティングを停止することでコンピューティング料金をとめることができますが、サブリソース料金は発生しつづけます。

■スタンダード ロード バランサー
時間：約 2.8 円
月額：2.8 [円/時間] x 24 [時間/日] x 31 [日] = 2,083.2 円
[ロードバランサー料金](https://azure.microsoft.com/ja-jp/pricing/details/load-balancer/)

■スタンダード (静的) パブリック IP アドレス
時間：約 0.56 円
月額：0.56 [円/時間] x 24 [時間/日] x 31 [日] = 416.64 円
[IPアドレス料金](https://azure.microsoft.com/ja-jp/pricing/details/ip-addresses/)

■マネージド ディスク
時間：約 3.4127 円
月額：3.4127 [円/時間] x 24 [時間/日] x 31 [日] = 2,539.0488 円
[マネージド ディスク料金](https://azure.microsoft.com/ja-jp/pricing/details/managed-disks/)

■サブリソースの合計料金
月額：5,038.8888 円

#サブリソース料金を停止するには
コンピューティングを削除することで、サブリソースの課金を停止することができます。今後利用する予定のないコンピューティングは停止するよりも削除することを推奨いたします。

#おわりに
"Azure Machine Learning 料金"と調べると、基本的にコンピューティングの料金がでてきますが、実際はサブリソースに関しても課金が発生します。
Azure Machine Learning を利用する上で、気をつけていきたいですね。
HTMLの基本的な書き方

#HTMLとは
***HTML***は、***HyperText Markup Language***の略で、主にwebサイトに表示される画面を作成するために使用されるマークアップ言語の1つ。
マークアップ言語は、***タグ***で囲む(Markup)ことでレイアウトや構造などを指定することができる。

# 基本的な書き方
HTMLのタグには開始タグ```<>```と終了タグ```</>```がある。タグは大文字、小文字どちらでも使用することができる。
まず、HTMLを記述する上での基本構造で重要なタグが以下の3つである。
■***\<html>...\</html>*** : HTMLの文章であることを宣言するタグ
■***\<head>...\</head>*** : 文章のヘッダ情報を指定するタグ
■***\<body>...\</body>*** : 画面に表示される部分を記述するタグ

例として、「Hello, world!」と画面に表示する場合は以下のように書ける。

```html
<html>
  <head>
    <title>タイトル</title>　
  </head>
  <body> Hello, world! </body>
</html>
```

その他のタグについてもいくつかまとめておく。

| タグ |説明|
|---  |---   | 
|\<title>  |ページのタイトルを作成する。  |　
|\<h1>  |見出しを作成する。h1～h6まであり、h1が最大 。 |　
|\<p>|文章の段落を表す。　   |　
|\<br>|改行する。|
|\<ol>|番号付きの箇条書き。|
|\<div>|囲った要素をグループ化する。|
|\<img>|画像を表示する。|
|\<a>|リンクを埋め込む。|
|\<script>|スクリプトを埋め込む。|
python 文字列を並び替えて列挙し、リストにする（競プロ用）


## 入力された文字列を並び替えてリストにする(昇順)

```py
import itertools

s = input()
words = ["".join(i) for i in itertools.permutations(s)]
words.sort()
print(words)
```

## 出力 ('abcd'を入力した場合)

```py
['abcd', 'abdc', 'acbd', 'acdb', 'adbc', 'adcb', 'bacd', 'badc', 'bcad', 'bcda', 'bdac', 'bdca', 'cabd', 'cadb', 'cbad', 'cbda', 'cdab', 'cdba', 'dabc', 'dacb', 'dbac', 'dbca', 'dcab', 'dcba']
```


## 入力された文字列を並び替えてリストにする(降順)

```py
import itertools

s = input()
words = ["".join(i) for i in itertools.permutations(s)]
words.sort(reverse=True)
print(words)
```

## 出力 ('abcd'を入力した場合)

```py
['dcba', 'dcab', 'dbca', 'dbac', 'dacb', 'dabc', 'cdba', 'cdab', 'cbda', 'cbad', 'cadb', 'cabd', 'bdca', 'bdac', 'bcda', 'bcad', 'badc', 'bacd', 'adcb', 'adbc', 'acdb', 'acbd', 'abdc', 'abcd']
```

## 参考資料

[python公式ドキュメント(itertools.permutations)](https://docs.python.org/3/library/itertools.html#itertools.permutations)
RedshiftにSSH接続してread_sql, to_sqlする方法

セキュリティの観点から、AWS Redshiftへは踏み台経由でSSH接続する場合が多いと思います。
そこで、今回はデータサイエンティスト・アナリストが良く使うであろう`pandas.read_sql()`や、ORMのSQLAlchemyを利用したpandas.DataFrameの`to_sql()`を、踏み台経由でSSH接続したRedshiftで使用する方法を紹介します。
## ライブラリ
```
psycopg2-binary==2.9.1
sqlalchemy==1.4.25
sshtunnel==0.4.0
```

## メソッド定義
新たにread_sql, to_sqlメソッドを定義する。

```python
import psycopg2

from sqlalchemy import create_engine

from sshtunnel import SSHTunnelForwarder


def read_sql(ssh_host, ssh_port, ssh_username, ssh_pkey, dbhost, dbport, dbuser, dbpassword, database, query):
    # Redshiftに接続
    with SSHTunnelForwarder(
        (ssh_host, ssh_port),
        ssh_username=ssh_username,
        # 秘密鍵
        ssh_pkey=ssh_pkey,
        remote_bind_address=(dbhost, dbport),
    ) as server:
        conn = {
            'host': 'localhost',
            'port': server.local_bind_port,
            'user': dbuser,
            'password': dbpassword,
            'database': database
        }
        with psycopg2.connect(**conn) as conn:
            return pd.read_sql(query, con=conn)


def to_sql(ssh_host, ssh_port, ssh_username, ssh_pkey, dbhost, dbport, dbuser, dbpassword, database, schema, table_name, df, if_exists):
    # Redshiftに接続
    with SSHTunnelForwarder(
        (ssh_host, ssh_port),
        ssh_username=ssh_username,
        # 秘密鍵
        ssh_pkey=ssh_pkey,
        remote_bind_address=(dbhost, dbport),
    ) as server:
        engine = create_engine(f'postgresql://{user}:{password}@localhost:{server.local_bind_port}/{database}')
        df.to_sql(table_name, engine, schema=schema, index=False, if_exists=if_exists)
```

## 使い方
### 接続情報
踏み台サーバー、接続先のDBの情報を記載する。

```python
config = {
    # ssh config
    'ssh_host': '*****',
    'ssh_port': *****,
    'ssh_username': '*****',
    'ssh_pkey': '*****', # 秘密鍵の絶対パス
    
    # db config
    'dbhost': '*****',
    'dbport': *****,
    'database': '*****',
    'dbuser': '*****',
    'dbpassword': '*****'
}
```
### read

```python
# read sql from redshift
read_sql(**config, query='select top 10 * from hoge.fuga')
```

### write

```python
# create from pandas DataFrame into redshift
df = pd.DataFrame([{'Name': 'Ram', 'Age': 50},
   {'Name': 'Bhim', 'Age': 23},
   {'Name': 'Shyam', 'Age': 25}]
)
to_sql(**config, schema='sandbox', table_name='test', df=df, if_exists='replace')
```
M1 MacBook Airにgfortranとgnuplotをインストールした時の流れ

こんにちは、Rinjuです。物理を勉強したり音楽を作ったりしてます。
M1 MacBook Air(2020)を購入し、gfortranとgnuplotをインストールしてFortran環境を作りました。OSはBig Sur(11.6)です。
以前Macにgfortranを入れた時には以下のページ(牛島 省様 著)を参考にさせていただきました。今回はMacのチップがIntelではなくApple M1という違いがありますが、同様の手順を踏んでやることにしました。

http://www.compe.media.kyoto-u.ac.jp/syoseki/mac/mac-gfortran.html

#1 Command Line Toolsをインストール
https://developer.apple.com/download/all/?q=command%20line%20tools

上のリンクから、Command Line Tools 13.1をインストールしました。
Macでコマンド操作をやるためのツールのようです。
ここら辺に関しては、細かいことはわからず言われるままにやっている感じです。

#2 Homebrewをインストール
https://brew.sh/index_ja

好きなソフトの一つです。パッケージ管理ソフトというそうです。
上のリンクからコマンドをターミナルにコピペして、言われるがままパスワードを打ってインストールしました。

https://brew.sh/2021/02/05/homebrew-3.0.0/

2021年2月にM1対応したそうです。

「Next Steps」に従って、パスを通すために2つのコマンドを打ち、「brew help」と入力すると、

```
Example usage:
  brew search TEXT|/REGEX/
  brew info [FORMULA|CASK...]
  brew install FORMULA|CASK...
  brew update
  brew upgrade [FORMULA|CASK...]
  brew uninstall FORMULA|CASK...
  brew list [FORMULA|CASK...]

Troubleshooting:
  brew config
  brew doctor
  brew install --verbose --debug FORMULA|CASK

Contributing:
  brew create URL [--no-fetch]
  brew edit [FORMULA|CASK...]

Further help:
  brew commands
  brew help [COMMAND]
  man brew
  https://docs.brew.sh
```

のように出て来ました。
ちゃんとパスが通ったようです。

#3 GCC(gfortran)をインストール
gfortranはgccというパッケージに含まれているので、gccごとインストールしました。

```
brew install gcc
```

と、ターミナルに入力しました。
1分経たずに終わって驚きました。前は1時間はかかった気がします。WiFiが良かったのだろうか……。
途中で間違えてescapeボタンを押してしまい戦慄しましたが影響なかったようです。

インストールが終わったら

```
gfortran -v
```

と入力してみると、色々書いてあった後に

```
gcc version 11.1.0 (Homebrew GCC 11.2.0_1) 
```

とgccのバージョンが表示されました。インストールは成功したようです。

最後に自分のプログラムをgfortranでコンパイルしてみると、きちんと.outファイルが出て来ました。

#4 gnuplotのインストール
やはり同様に以下のページ(牛島 省様 著)を参考にしてgnuplotのインストールをしました。

http://www.compe.media.kyoto-u.ac.jp/syoseki/mac/mac-gnuplot.html



```
brew install gnuplot
```

とターミナルに入力しました。gccの時よりも時間がかかった気がします。

```
gnuplot
```

と入力してgnuplotを起動、

```
plot x
```

と入力するとグラフが出力されました。インストールは成功したようです。

無事Fortran環境が作れましたので、楽しい研究ライフを目指して精進していこうと思います。

Rinju
[競プロ][Max Subarray] Kadane’s Algorithm解説

最大部分配列問題を解くとよく目にするKadane’s Algorithm
コードを見てもイマイチ動きをイメージしづらく、日本語での解説も少ないと思ったのでまとめてみる。

## 考え方

まずKadane’s AlgorithmはDynamic Programming問題と考えると理解しやすい。
前提として整数を要素にもつ配列をAとする。

DP[i]をAにおけるi以下の任意の要素(A[0]...A[i-1])から要素i(A[i])までの部分配列における和の最大値と定義する。(最初の要素から要素iまでの最大値ではないことに注意)
すると初期状態と状態遷移は下記のようになる。

- 初期状態：DP[0] = A[0]
- 状態遷移：DP[i+1] = max(A[i+1], DP[i]+A[i+1]) 
(意味：DP[i+1]はA[i+1]もしくはDP[i]にA[i+1]を足したもの)

**このときDP[n-1]が答えになるわけでなく、DP[0]...DP[n-1]の中での最大値が答えとなる。**

## 文章での説明

下記の配列Aを考える。
[1, 2, 3, -4, -5, 6]

配列[1,2]の最大部分配列和は3である。
次に[1,2,3]の部分配列和を考えると候補は下記の3種類となる。

- [1,2,3]
- [2,3]
- [3]

しかし[1,2]の最大部分配列和は3と既にわかっているので実際に比較すべきものは下記に絞られる。

1. [1,2]の最大部分配列和と3の和
2. 3のみ

2は[1,2]の最大部分配列和が負の数になるときに選択される。

このアルゴリズムのポイントは各イテレーションでは要素iより前の要素のみを見ればいいということ。
それ以降の要素は次のイテレーション(i+1)以降で検証されるため。

## 練習問題

下記の問題を解いてみる。
1つ前の状態のみ覚えておけばいいのでDP配列を使わずsum変数のみで対応

[53. Maximum Subarray](https://leetcode.com/problems/maximum-subarray/)

```c++
int maxSubArray(vector<int>& nums) {
    int sum = nums[0];
    int ans = sum;
    for (int i=1; i<nums.size(); i++) {
        int num = nums[i];
        sum = max(sum+num, num);
        ans = max(ans, sum);
    }    
    return ans;
}
```
Could not find a package configuration file provided by "ifopt"

ROSでパッケージをcloneしてきて、catkin_makeしたときに以下のようなエラーが出た。


```
Could not find a package configuration file provided by "ifopt" (requested
version 2.0.1) with any of the following names:

ifoptConfig.cmake
ifopt-config.cmake
```

## 解決策

cloneしたパッケージにcdして以下のコマンドを実行する。

カレントディレクトリが ~/catkin_ws/src/cloneしたパッケージ にあるとして

```
cmake .. && make install
```

このあとcatkin_wsにcdしてcatkin_makeすればmakeが通る。
ArgoCDをコンパイルするときに発生するエラー: module go.opentelemetry.io/otel@latest found (v1.2.0), but does not contain package go.opentelemetry.io/otel/api/metric を解消する方法

# 概要

ArgoCDが依存しているgo-redisが依存しているパッケージのgo.opentelemetry.ioの指定が食い違っていて表題のエラーが発生することがある。これを解消する方法を説明する。

# エラー全文

```
github.com/focas/focas/experimental/argocd-go imports
	github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned imports
	github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/typed/application/v1alpha1 imports
	github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1 imports
	github.com/argoproj/argo-cd/v2/util/helm imports
	github.com/argoproj/argo-cd/v2/util/cache imports
	github.com/go-redis/redis/v8 imports
	github.com/go-redis/redis/v8/internal imports
	go.opentelemetry.io/otel/api/metric: module go.opentelemetry.io/otel@latest found (v1.2.0), but does not contain package go.opentelemetry.io/otel/api/metric
```

# 解消方法

go-redisの特定のコミットを取得する。

```bash
go get github.com/go-redis/redis/v8@1f32092a3b04c21b6e8e51e2c94c03448d14a2c9
```

# 参照

- [undefined: otel.Meter or cannot find package "go.opentelemetry.io/otel/api/trace" · Issue #1534 · go-redis/redis](https://github.com/go-redis/redis/issues/1534)
Gitコマンド sparse-checkout使ってみた

#はじめに
　先日、社内の古参プロジェクトをいじる機会があり、リポジトリをcloneしようとしたら巨大過ぎたので、いじりたい一部分だけcloneできないかと調べると都合の良いコマンドがあったので使ってみました。

#git sparse-checkout
　昔から存在はしていたコマンドですが、ここ数年で改修も入り使いやすくなってるのではないかと思います。

<dl>
  <dt>・Git 1.7</dt>
  <dd>2010年2月 リリース</dd>
  <dd>git sparse-checkout 導入</dd>
  <dt>・Git 2.25</dt>
  <dd>2020年1月 リリース</dd>
  <dd>git sparse-checkout 機能改善</dd>
  <dd>Highlights from Git 2.25 - The GitHub Blog</dd>
  <dt>・Git 2.26</dt>
  <dd>2020年3月 リリース</dd>
  <dd>git sparse-checkout add 追加</dd>
  <dd>Highlights from Git 2.26 - The GitHub Blog</dd>
</dl>

#使ってみた
　試しにphpフレームワーク `phalcon` のリポジトリをcloneしようと思います。clone対象は `docker/8.0` に絞って行います。gitのバージョンは2.32.0を使用します。

```zsh
$ git --version
git version 2.32.0
$ mkdir -p qiita
$ cd qiita
$ git init .
$ git config core.sparsecheckout true ### sparsecheckoutを有効にします。
$ cat .git/config ### config確認
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
	ignorecase = true
	precomposeunicode = true
	sparsecheckout = true
$ echo "/docker/8.0" > .git/info/sparse-checkout ### 対象ディレクトリ指定
$ cat .git/info/sparse-checkout
/docker/8.0
$ git remote add origin git@github.com:phalcon/cphalcon.git ### リモートリポジトリの追加
$ cat .git/config
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
	ignorecase = true
	precomposeunicode = true
	sparsecheckout = true
[remote "origin"]
	url = git@github.com:phalcon/cphalcon.git
	fetch = +refs/heads/*:refs/remotes/origin/*
$ git pull origin master ### 取り込んでみる
remote: Enumerating objects: 231468, done.
remote: Counting objects: 100% (19901/19901), done.
remote: Compressing objects: 100% (7433/7433), done.
remote: Total 231468 (delta 14489), reused 16454 (delta 12247), pack-reused 211567
Receiving objects: 100% (231468/231468), 185.47 MiB | 2.49 MiB/s, done.
Resolving deltas: 100% (182723/182723), done.
From github.com:phalcon/cphalcon
 * branch                master     -> FETCH_HEAD
 * [new branch]          master     -> origin/master
$ tree . ### pullしたディレクトリ構造確認
.
└── docker
    └── 8.0
        ├── Dockerfile
        └── extra.ini

2 directories, 2 files
```

#感想
　狙い通り特定のディレクトリ配下のみ取り込むことができました。一部のディレクトリが肥大化し、その影響でリポジトリ全体が重くなっているプロジェクトも少なくないと思いますので、使い方次第では有効なツールになると思います。
　懸念点としては下記のように　`.git/objects/` 配下のボリュームはそれほど変わらないという点です。git上の歴史はすべて取り込んだうえで、一部ディレクトリのみをpullしているだけのようなので、歴史あるリポジトリに対して行う場合は、pullする際にそれなりの時間がかかると思います。

```zsh
### 今回のsparse-checkoutを使用した場合
du -sh .git/objects/
198M	.git/objects/

### 通常通りフルでcloneした場合
$ du -sh.git/objects/
199M	.git/objects/
```

#参考
・[Highlights from Git 2.25 - The GitHub Blog](https://github.blog/2020-01-13-highlights-from-git-2-25/)
・[Highlights from Git 2.26 - The GitHub Blog](https://github.blog/2020-03-22-highlights-from-git-2-26/)
・[Phalconリポジトリ](https://github.com/phalcon/cphalcon)
モーダルの切り替え

暇を持て余す社内ニートその３（多分）

モーダルの切り替え：解説でなく自分用
閲覧になった方は参考のURLへ移動するか、検索しなおすことをお勧めします。


HTMLはパクリ
・モーダルは待機状態イメージ。

#やってること
モーダル１：message-modal1　を開いてOKすると
モーダル２：message-modal2　を開く
モーダル２をキャンセル（insert-message-cancel ）したらモーダル１に戻る。

##HTMLの中

```html:html
<div class="modal fade" id="message-modal1">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h4 class="modal-title">モーダル1</h4>
        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
      </div>
      <div class="modal-body">
        <a data-toggle="modal" href="#message-modal2" class="btn btn-primary">モーダルを開く</a>
      </div>
      <div class="modal-footer">
        <a href="#" data-dismiss="modal" class="btn">閉じる</a>
        <a href="#" class="btn btn-primary">ただのボタン</a>
      </div>
    </div>
  </div>
</div>
<div class="modal fade" id="message-modal">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h4 class="modal-title">モーダル2</h4>
        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
      </div>
      <div class="modal-body">
       モーダル
      </div>
      <div class="modal-footer">
        <a href="#" data-dismiss="modal" id=insert-message-cancel class="btn">閉じる</a>
<!--ここで data-dismiss="modal"を使っているが不要かも。-->
        <a href="#" class="btn btn-primary">ただのボタン</a>
      </div>
    </div>
  </div>
</div>
```

##jqueryの中身
```jquery:jquery
<script>
/*モーダルの変更*/            
$(function(){
    changeModal('message-modal', 'message-modal2');
    function changeModal(beforeModal, afterModal) {
        $('#'+beforeModal).modal( 'hide' );
        $('#'+afterModal).modal('show');
    }
});

$('#insert-message-cancel').on('click', function () {
    changeModal('message-modal2', 'message-modal');
    function changeModal(beforeModal, afterModal) {
        $('#'+beforeModal).modal('hide');
        $('#'+afterModal).modal('show');
    }
}); 
<script>
```

♯参考資料
・モーダルから別のモーダルを表示する
https://qiita.com/tomlaw/items/1fd8edc9ca1522ad270e
参考にしたけどうまく使えそうになかった。
bootstrapの思想としては論外だけど、スクロール意識しないなら以下で十分だった。

```jquery:jquery
/*モーダルの上書き*/            
$(function(){
   $('#message-modal2').modal('show')
});
```


・Bootstrapでモーダルを複数重ねて表示する
（課題があって解決したらしいけど、応用できずにいる。）
https://slash-mochi.net/?p=3041

モーダル複数サンプル（ようわからん）
http://yebisupress.dac.co.jp/2018/06/11/tips_when_using_bootstrap_multiple_modal_overaly/
家の前が渋滞している日は家にいたくない(・´з`・)事前に察知して家から脱出しよう！ #渋滞 #東名 #道路情報

東名で事故などが発生して渋滞が発生すると、我が家近くのICからの車&そのひとつ前のICから抜け道を通ってくる車が多数通ることになり、家の前に渋滞が発生することが多いのです。
家にいても**渋滞中の車の振動やクラクションの音など、<font color="#ff0000">とにかく超うるさい。</font>**
できれば家にいたくないのですが、渋滞が始まってから家を出ると渋滞に巻き込まれて大変ですし、一度家を出てしまうとほとぼりが冷めるまで家に帰れないのです。
それなら渋滞が起きる前、つまり事故情報を集めることができれば、渋滞が起きる前に家を出れるんじゃない？それに、出先で渋滞が起きていることを知れたら家に帰る時間を調整することが可能なんじゃない？と考えました。

TwitterにNEXCO中日本のアカウントがあり、渋滞の情報を発信しています。
それ以外にもTwitterでは事故情報を発信してくれている人がたくさんいるので、情報には困らないのでは？と考えました。
自分が必要なところだけの情報が欲しいので、アカウントやハッシュタグだけではなく、キーワード検索していきます。

以下図が家周辺の超簡易地図です。<font color="#ff8c00">**オレンジ色**</font>の渋滞が起きやすい道に囲まれています。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2122199/55603bf5-0385-caca-32b2-1dab6a3e3dde.jpeg" width=60%>

今回はIFTTTを使って**ノーコード**で問題を解決してたいと思います。

#使うもの
LINE Notifyはログインして、友達追加&通知してほしいグループにメンバー登録しておきます。

https://notify-bot.line.me/ja/

ログインが完了したらIFTTT側に戻ってLINE Notifyを使えるようにしていきます。
IFTTTでLINE Notifyを使う場合は最初に自分のLINEアカウントとリンクさせる必要があります。

https://ifttt.com/home

#IFTTTで実装
実装というより、設定という感じですね。
キーワード検索は ``filter:images`` を使って指定します。
検索したいキーワードは`` "" ``でくくります。
【参考】[3分で簡単ニュースフィードをIFTTTとSlackで作ってみた](https://qiita.com/canonno/items/4877c300b8e60b8467c4)

|IF：トリガー|TTT：実行|
|:-:|:-:|
|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2122199/196c1ece-f62e-2af8-b198-542cf3c40579.jpeg" width=70%>|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2122199/ffc8cb02-4038-ada5-fcde-a3a174f4b6b5.jpeg" width=70%>|

#LINEに情報が届きました！
キーワードをゆるめに設定(※)しているので、まったく関係ないエリアの情報が入ってきていますが、これで実装完了です。
※キーワードを細かく指定すると家バレしますので、記事内では範囲指定せず設定しています。

|実行結果：LINE画面1|実行結果：LINE画面2|
|:-:|:-:|
|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2122199/b60ae668-47c3-5db8-ccf4-a5f9f25d5ca3.jpeg" width=70%>|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2122199/767025f0-9b4a-9adb-3c33-58a3c01a0230.png" width=70%>|

#課題解決できたか
渋滞情報がTwitterからLINEへ通知され、それをキャッチすることができるようになったことで、渋滞前に脱出することができました。家に残っている家族に渋滞していたか確認したところ、やはり渋滞していたとのこと。脱出成功です！
そして、帰宅前に渋滞情報を取得することができ、帰りのルートを考えたり、ほとぼりが冷めたころに帰るよう調整することができました。
それ以外にも自分が欲しい地域（キーワード）の渋滞が発生するタイミングで情報がLINEに届くようになり、関係ない情報もたまに来ますが、SAのお土産情報なども入ってきて楽しいです。

#さいごに
ノーコードで簡単にLINEに通知してくれるなんて驚きでした。
モジュールをガシガシ書く方が好きな方なのですが、こういうことも簡単にできると知ることができて良かったです。
渋滞情報をTwitter以外からも持ってくることができるようバージョンアップしていきたいです。
C# ファイルを複数移動する方法

```
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;

namespace for文2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {

            string folderFrom = @"C:\Users\8100825\Desktop\A"; //移動元のフォルダー
            string folderTo = @"C:\Users\8100825\Desktop\B"; //移動先のフォルダー


            foreach(string pathFrom in System.IO.Directory.EnumerateFiles(folderFrom))
            {

                //移動先のパスを生成
                string pathTo = pathFrom.Replace(folderFrom, folderTo);

                //移動先のフォルダーが存在するか確認し、なければ作成します
                string targetFolder = System.IO.Path.GetDirectoryName(pathTo);
                if (System.IO.Directory.Exists(targetFolder) == false)
                {
                    System.IO.Directory.CreateDirectory(targetFolder);
                }

                //１ファイルの移動実行。同名のファイルがある場合は上書きします
                System.Diagnostics.Debug.WriteLine("移動" + pathFrom + "→" + pathTo);
                System.IO.File.Move(pathFrom, pathTo);
            }

        }
    }
}
```

「開始」→「button1」を押すとAフォルダにあるファイルがBフォルダに全て移動する

参考サイト
https://www.umayadia.com/cssample/sample0201/Sample260MiltipleFileMove.htm?pos=0
React Router v6でのRouteコンポーネントの扱い方の変更点

# はじめに
[React Router v6](https://github.com/remix-run/react-router)が2021年11月3日にリリースされたのですが、コンポーネントの名前やデフォルトが大きく変わりました。本記事では、よく使う構文についての変更点を紹介します。詳しくは[https://remix.run/blog/react-router-v6](https://remix.run/blog/react-router-v6)を参照してください。

# コード例
ルーティングをするための簡単なサンプルコードです。
`/`にアクセスすると`Home`、`/page`にアクセスすると`Page1`がそれぞれ表示されます。`/page2`にアクセスすると`/page1`にリダイレクトされます。それ以外のURLは`Page404`が表示されます。
## React Router v5
```example-v5.js
import React from "react";
import {
    BrowserRouter as Router,
    Switch,
    Route,
    Redirect,
} from "react-router-dom";
import Home from "home.js"
import Page1 from "page1.js"
import Page404 from "page404.js"

function App() {
    return (
        <Router>
            <div className="App">
                <Switch>
                    <Route exact path='/' component=Home/>
                    <Route exact path='/page1'>
                        <Page1 />
                    </Route>
                    <Route exact path='/page2'>
                        <Redirect to='/page1'/>
                    </Route>
                    <Route component=Page404/> {/*not foundの時*/}
                </Switch>
            </div>
        </Router>
    );
}

export default App;
```

## React Router v6
```example-v6.js
import React from "react";
import {
    BrowserRouter as Router,
    Routes,
    Route,
    Navigate,
} from "react-router-dom";
import Home from "home.js"
import Page1 from "page1.js"
import Page404 from "page404.js"

function App() {
    return (
        <Router>
            <div className="App">
                <Routes>
                    <Route path='/' element={<Home/>} />
                    <Route path='/page1' element={<Page1/>} />
                    <Route path='/page2' element={<Navigate to='/page1' />} />
                    <Route path='/*' element={<Page404/>} /> {/*not foundの時*/}
                </Routes>
            </div>
        </Router>
    );
}

export default App;
```

# 変更点
* **コンポーネントの名前が変更**されました。
    * `Switch` → `Routes`
    * `Redirect` → `Navigate`
    * 間違えると次のようなメッセージが出ます。

    ```
Attempted import error: 'Switch' is not exported from 'react-router-dom'
```

* `<Route>`の中身は`element`で指定するのが必須になりました。`component`での指定はできません。また、`<Route> <Page1 /> </Route>`というように書くと次のようなエラーが出ます。

```
Error: [Page1] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>
```

* exact句を書かなくても、ディレクションが一意に定まるようになりました。v5では、exactをつけない場合、"/"から始まるリンク先は"/"も"/page1"も全て"/"に遷移してしまっていた(前方一致)のですが、v6では**デフォルトで全文一致**で探してくれるようになりました。
* これに関連して、pathを指定しない場合の挙動も変わりました。v5ではpathを指定しないと全てのURLにマッチしているのと同じことになりましたが、v6では何にもマッチしません。**v6で全てのURLにマッチさせたい場合は`/*`をpathに指定します。**

# まとめ
React Router v6の変更点のうち、多くの人に影響しそうな部分をかいつまんで紹介しました。
まとめると、SwitchとRedirectの名前と、pathの検索方法が変わったということです。
詳しくは[https://remix.run/blog/react-router-v6](https://remix.run/blog/react-router-v6)や[Github](https://github.com/remix-run/react-router)を参照してください。
firebase firestoreのaddとsetの違い、setのmargeとupdateの違い

自分用メモ（うろ覚え）

add：ドキュメントのidを自分で指定できない
set：ドキュメントのidを自分で指定できる

setのmarge：既に登録済みのフィールドを、上書きせずに新たに値を追加することが可能
update：既に登録済みのフィールドを更新

https://qiita.com/AyakoKataoka/items/884ee2e5d6a501d3ea7d

https://tomokazu-kozuma.com/difference-between-set-and-update-when-updating-cloud-firestore-data/
Installed Build Tools revision 31.0.0 is corrupted というエラーの原因はAGPが4系だからかもしれない

`compileSdkVersion` と `buildToolsVersion` を 31 に上げると以下のようなエラーがでることがあります。

> Installed Build Tools revision 31.0.0 is corrupted. Remove and install again using the SDK Manager.


エラーメッセージにはSDK Managerから再インストールしろと書いてありますが再インストールしても治らない場合は、AGPを7系にあげるとビルドエラーが解消するかもしれません。試してみましょう。

```gradle:build.gradle
buildscript {

    dependencies {
        classpath 'com.android.tools.build:gradle:7.0.x'
        ...
    }
}
```

Googleで検索すると、「３０に下げれば良い」とか、「ファイルが足りていないので解消しましょう」とか出てきますが、AGPを上げるのが正攻法で良いと思います。上げれない理由がない限りは上げてしまいましょう。

https://stackoverflow.com/questions/68387270/android-studio-error-installed-build-tools-revision-31-0-0-is-corrupted
遺伝研スパコンでRNAseqを最速・自動で行う

[東京理科大学朽津研究室](https://kuchitsu-lab.web.app/ja)B4の前田です。シロイヌナズナのRNAseqやってます。

遺伝研スパコンにログインする方法や、sshの使い方については解説しません。
多少RNAseq解析に対して知識があり、RNAseqをもっと高速にできないか、または自分でできないか？と考えている方向けに解説します。

遺伝研スパコンのUGEの問題は試行錯誤しまくってやっとわかったので、もっとエレガントに解決できる方がいましたら教えて下さい :[

## 使うもの 
Nextflow
遺伝研スパコン

### Nextflowとは
ワークフローツールです。発現解析ではsamtoolsや、fastQC,salmon....など大量のツールをインストールする必要があります。また、時間がかかる処理の出力を何度も次のツールに入れなくてはならない上に、サンプルデータが10種類を超えることも珍しくありません。また、ツールの依存関係やバージョン管理も非常に煩雑です。これらをまとめて解決してくれるのがワークフローツールです。更にDocker,Singularity
などのコンテナを用いることで再現可能な実行環境を構築します。
https://www.nextflow.io/

* もうpythonをインストールする必要はありません。

* fastQCをインストールする必要はありません。

* trimgaloreをインストールする必要はありません。

PCを変えても全く同じ環境を再現できます。そのため、手元で行った解析と全く同じことをスパコンで行ったり、他人が行った解析を自分が再現したりできます。


今回はNextflowで既に書かれたワークフローで世界中の人がメンテナンスしている既存パイプラインを使用します。
[https://nf-co.re/rnaseq]

基本的な使用方法はusageを見てください。
以下はnf-core/RNAseqと遺伝研スパコン特有の問題の解決方法です。

## nf-core/RNAseqと遺伝研スパコン特有の問題の解決方法

sshで遺伝研のスパコンにログインします。

`qlogin -l mem_req=16g,s_vmem=16G`

この時memoryを指定するのはjavaを実行したいからです。

`export MALLOC_ARENA_MAX=2`

も実行します。

`curl -s https://get.nextflow.io | bash`

するとカレントディレクトリに実行バイナリが落ちてきます。

`./nextflow run nf-core/rnaseq -profile test,singularity`

で動くか確認してください。(エラー出たら権限関連かも、Linux 実行ファイル 権限とかで検索してください)


## RNAseqを行う
遺伝研のスパコンはUGEというジョブ管理システムで動いています。
このUGE（or遺伝研の設定？）についてハマりどころが結構あるので気をつけてください

- 間違ったリソースパラメータを指定すると永遠にqw(que waited)の状態になる、エラーは出ない。
- 実行されないのは間違ったパラメータ指定してるからなのに、混んでるから実行されないんだと勘違いしてしまう！！！！
- キューはshort.qで十分。並行処理の1処理自体は時間がかからない。
- nextflowのconfigでmemoryを指定すると、h_rt/h_rss/mem_freeが勝手に指定される。遺伝研のスパコンではこれらを指定するとqwから脱出できなくなる。

## h_rt/h_rss/mem_freeが勝手に指定される問題の解決法

```nextflow.config
profiles {
    uge {
        process{
            executor   = 'uge'
            penv = "def_slot"
            clusterOptions ="-S /bin/bash -l s_vmem=16G -l mem_req=16G -l short -cwd -o stdout -e stderr"
            withName: '.*' {                
                time=null
                memory = null 
                }
        }
        singularity.autoMounts = true
        docker.enabled         = false
        singularity.enabled    = true
        podman.enabled         = false
        shifter.enabled        = false
        charliecloud.enabled   = false
    }
 }    
```
`.nextflow/assets/nf-core/rnaseq/nextflow.config`に↑のようなプロファイルを追加する。

`.nextflow/assets/nf-core/rnaseq/modules/nf-core/software/qualimap/rnaseq/main.nf`
から`def memory = getMemory()+"G"`
みたいなところを探す、だいたい33行目周辺にある。
これを    `def memory     = 16 + "G"`に書き換える。
nextflowのmemoryをnullにしちゃったのでgetMemoryでぬるぽになる。

## 実行する
`./nextflow run nf-core/rnaseq  --input ./samplesheet.csv --genome TAIR10 -profile uge -resume --save_reference --max_memory 16.GB`
を実行する。

**qsubは使わないことに注意。**
nextflowがqueを勝手に作って投げてくれる。
【帳票ツール】JavaScriptをベースとしたStimulsoft Reports.JSをとにかく試してみる

以前、[【帳票ツール】ブラウザ(HTML、JavaScript)で、帳票デザイン開発 : Stimulsoft](https://qiita.com/REQWARE/items/169479c4c94dc41c9722)で紹介した帳票ソリューションである「Stimulsoft」をさくっと試す方法について書いてみます。今回は、HTML化が容易な、JavascriptライブラリのStimulsoft Reports.JSを使用します。

#前提
gitとnpmはインストール済みとします。

# Stimlsoftのサンプルアプリの場所（github）
https://github.com/stimulsoft/Samples-JS

こちらのリポジトリには、Node.js、JavaScript、ASP.NET、PHP、AngularJS、Angular、React、Vue.jsアプリケーションのレポートツールであるStimulsoftReports.JSのサンプルが含まれています。
#サンプルアプリのクローン
インストール先のディレクトリに移動した後に、リポジトリをクローンします。

```shell
$ git clone https://github.com/stimulsoft/Samples-JS.git 

$ ls Samples-JS/
ASP.NET/    Demo/        LICENSE.md  README.md       Vue.js/
Angular/    Java/        Node.js/    React/
AngularJS/  JavaScript/  PHP/        THIRD-PARTY.md
```

#npmモジュールのインストール
今回は、React版のデザイナーを確認してみます。（01. Working with report designer）

```shell
$ cd 'Samples-JS/React/01. Working with report designer/'

$ npm install
```

#環境の起動
```shell
$ npm start
```

#動作確認
あとは、ブラウザから`http://localhost:8080`にアクセスするだけです。
以下のような画面を確認できれば成功です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486327/182f8deb-9284-890e-ab8d-000d323e4f99.png)

#まとめ
Stimulsoft Reports.JSは、帳票に関わる開発・操作をWeb（ブラウザ）のみで完結します。しかも、Stimulsoftは様々な開発言語に対応しており、サンプルアプリからすぐに動作を確認することができます。

※注）Stimulsoftは日本語対応していますが、github上のサンプルアプリには、日本語ファイルが含まれていません。

#追記
日本語化対応について記載しました。
[【帳票】Stimilsoft Reports.jsの日本語化について](https://qiita.com/REQWARE/items/a667883012b465decc34)
kotlin メモ

 ボタンのid.setOnClickListener {
            //ボタンの動作
        }

Kotlin のコレクションは、「読み取り専用」と「書き込み可」のインターフェースが明確に分かれている。
listOf(), mapOf() など、関数でインスタンスを生成する。
Stream API に用意されているような filter() などのメソッドが、 Iterable などに定義されている。
コレクションの種類
List
Map
Set

Kotlin の List や Set はあくまで「読み取り専用」であり、「イミュータブル」ではない。
例えば、以下のようなコードを書くと、簡単に List の中身を変更できてしまう。



＋ーX÷　四則演算に使う
formula.text = "${formula.text}+"
            addList(nStr,'+')                 //後述、nStrを小数に変換しnListに入れ、"+"をoListに入れる。
            nStr = ""                         //nStrを空に戻す

＋などの演算子の時点で一度nStrを空にする
１２３４＋　となったら　１２３４　と　＋　に分ける


＝　イコールボタン

formula.text = "${formula.text}="
    addList(nStr,'=')
    var result = calcualte().toString()
    formula.text = result
    nStr = result
    nList.clear()
    oList.clear()

計算の結果を　nStrに送る　結果をつかって続けて計算できる
SQLiteのTZの取り扱い注意点



```zsh
% cat timezone_consideration.sh 
#!/bin/sh

sqlite3 << EOF
/** TZ付きの時刻データ **/
select datetime('2020-07-01T07:14:16+00:00'); /** そのままの時刻が表示される **/
select datetime('2020-07-01T07:14:16+09:00'); /** このままだと9時間前の時刻が取得される **/

select datetime('2020-07-01T07:14:16+00:00', 'localtime'); /** 'localtime'を引数としてセット => 2020-07-01 16:14:16 **/
select datetime('2020-07-01T07:14:16+09:00', 'localtime'); /** 'localtime'を引数としてセット => 2020-07-01 07:14:16 **/

select "-------------------";

/** TZが付いていない時刻 **/
select datetime('2020-07-01 07:14:16');  /** そのまま表示される **/
select datetime('2020-07-01 07:14:16', 'localtime');  /** local TZの時間オフセットが反映されて表示される **/

EOF
% ./timezone_consideration.sh 
2020-07-01 07:14:16
2020-06-30 22:14:16
2020-07-01 16:14:16
2020-07-01 07:14:16
-------------------
2020-07-01 07:14:16
2020-07-01 16:14:16
% 

```
AWS MFA（多要素認証 / 二段階認証）の設定

#### 前提
Google Authenticatorをインストールしていることを前提とします。

#### 手順

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664818/7398ea3d-c46f-c5e5-8b10-ac3c7f3e013f.png)

AWSにサインインします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664818/ace92b92-c047-59a7-daf8-2a98ec2a5d21.png)

右上のユーザー名をクリックして「マイセキュリティ資格情報」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664818/a39c0607-004a-e76e-ee32-0e3d6ff90196.png)

多要素認証（MFA）の「MFAデバイスの管理」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664818/296e0030-2ab4-8862-b865-eb455a1cf919.png)

「仮想MFAデバイス」を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664818/f1238aca-8ca2-25c5-c166-013053ad9806.png)

QRコードの表示をクリックして、QRコードを表示させます。
QRコードをGoogle Authenticatorで読み取ります。


Google Authenticatorで右下の「＋」をクリックしてQRコードを読み取ります。

読み取ると６桁のコードが出てきます。
時間がたつと認証コードが変更します
（例）123123 ->  345345

認証コード１に表示されているコードを入力します。
認証コード２に次に表示されるコードを入力します。

同じ認証コードを入力しないように気を付けてください。

MFA デバイスの割り当てに登録されていることを確認して、サインアウトします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664818/8708c7a4-eeba-c9b1-4671-c596244dd876.png)


再度、サインインすると、認証画面になりますので、Google Authenticatorよりコードを確認して入力すればサインインできます。


#### 終わりに

Google Authenticatorのインストール・導入手順は省きました。
認証コード１・認証コード２のところで詰まったので、備忘録として書きました。
postgresql  calculate and order tables by size


```sql
select table_name, pg_size_pretty( pg_relation_size(quote_ident(table_name)) )
from information_schema.tables
where table_schema = 'public'
order by pg_relation_size(quote_ident(table_name)) desc;
```

---

refer：

https://stackoverflow.com/a/58916394

https://www.cnblogs.com/mchina/archive/2013/04/19/3028573.html
MinIOをdocker-composeで構築する。


````
  minio:
    image: minio/minio
    ports:
      - "9000:9000" // API用
      - "9001:9001" // コンソール画面用
    environment:
      MINIO_ROOT_USER: minio            
      MINIO_ROOT_PASSWORD: miniosecret  
    command: server /export --address :9000 --console-address :9001
````

`command`の`--address :9000`でAPIのポート番号を指定し、`--console-address :9001`でコンソール画面のポート番号を指定しています。


コンソール画面に遷移するために、localhost:9001を開くとログイン画面に遷移する。

そこで、ユーザー名とパスワードを入力すればログインが可能

````
      MINIO_ROOT_USER: minio            
      MINIO_ROOT_PASSWORD: miniosecret  
````
Docker ComposeでExpressとRedisを接続できないとき

## 出会ったエラー
Docker Compose使わないとできるのに、使うとこんなエラーが出ました。

```
Error: connect ECONNREFUSED 127.0.0.1:6379
```

## TL;DR
`docker-compose.yml`と`app.js`はこんな感じにする

```yml:docker-compose.yml
version: '3'
services:
  express:
    build: .
    volumes:
      - .:/app
    tty: true
    ports:
      - 3000:3000
    environment:
      - NODE_ENV=development
      - PORT=3000
      - SESSION_SECRET=hogehoge
      - REDIS_HOST=redis_db
      - REDIS_PORT=6379
    depends_on:
      - redis_db
  
  redis_db:
    image: redis:latest
    ports:
      - 6379:6379
```

```js:app.js
var session = require('express-session');
var RedisStore = require('connect-redis')(session)
var redis = require('redis')

var redisClient = redis.createClient({
  url: `redis://${process.env.REDIS_HOST}:${process.env.REDIS_PORT}`
})

app.use(session({
  secret: process.env.SESSION_SECRET,
  store: new RedisStore({
    client: redisClient,
    prefix: 'sid:',
  }),
}))
```

## ダメな例

ググった情報でこう書いてたけど、これはlocalhostでしか動きません。

```js:app.js
var session = require('express-session');
var RedisStore = require('connect-redis')(session)
var redis = require('redis')

var redisClient = redis.createClient()

app.use(session({
  secret: process.env.SESSION_SECRET,
  store: new RedisStore({
    client: redisClient,
    host: process.env.REDIS_HOST,
    port: process.env.REDIS_PORT,
    prefix: 'sid:',
  }),
}))
```
Python3: Google Cloud Storage にアクセス

GCE の Ubuntu 21.10 で確認した方法です。GCE で実行するので、認証の部分のコードを省略できます。

スクリプトでアクセスする方法はこちら
[Google Cloud Storage にスクリプトでアクセス](https://qiita.com/ekzemplaro/items/cd648c8f14c7421a928b)

バケットの一覧

```py:list_bucket.py
#! /usr/bin/python
#
#   list_bucket.py
#
from google.cloud import storage
#
client = storage.Client()
#
for bucket in client.list_buckets():
    print(vars(bucket)['name'])
    print()
#
```

ファイルの一覧

```py:list_files.py
#! /usr/bin/python
#
#   list_files.py
#
from google.cloud import storage
#
bucket_name = 'bucket001'
client = storage.Client()
#
for file in client.list_blobs(bucket_name):
    print(file.name)
#
```

ファイルのダウンロード

```py:get_file.py
#! /usr/bin/python
#
#   get_file.py
#
from google.cloud import storage
#
bucket_name = 'bucket01'
fname = 'file01.txt'
gcs_path='folder_aa/' + fname
local_path='./' + fname
client = storage.Client()
#
bucket=client.get_bucket(bucket_name)
blob=bucket.blob(gcs_path)
#print(blob.download_as_string())
#
blob.download_to_filename(local_path)
```
argocdのGithubとのSSO連携した話

##はじめに
argocdを導入し、Githubアカウントでログイン出来るようになればいいなーと思い立ち、Githubとの連携を試してみました。
ここでは、ローカルに立てたargocdへgithubアカウントへ接続できるのか試した検証結果を備忘録として記します。

###前提
・mac環境にk8s clusterを作成し、そこにargocdを載せる
・mac: macOS Big Sur version11.6

##SSO連携の前段階
argocdのプロジェクトを管理するのにコマンドが必要なのでインストールする

```
# brew tap argoproj/tap
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 2 taps (homebrew/core and homebrew/cask).
==> Updated Formulae
Updated 9 formulae.
==> Updated Casks
Updated 6 casks.

==> Tapping argoproj/tap
Cloning into '/usr/local/Homebrew/Library/Taps/argoproj/homebrew-tap'...
remote: Enumerating objects: 382, done.
remote: Counting objects: 100% (113/113), done.
remote: Compressing objects: 100% (80/80), done.
remote: Total 382 (delta 65), reused 76 (delta 32), pack-reused 269
Receiving objects: 100% (382/382), 67.96 KiB | 2.34 MiB/s, done.
Resolving deltas: 100% (220/220), done.
Tapped 1 formula (15 files, 85.9KB).
```

```
# brew install argoproj/tap/argocd
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/core).
==> Updated Formulae
Updated 6 formulae.

Warning: Use argocd instead of deprecated argoproj/tap/argocd
Warning: Use argocd instead of deprecated argoproj/tap/argocd
Warning: argocd 2.1.3 is already installed and up-to-date.
To reinstall 2.1.3, run:
  brew reinstall argocd
```

##SSO連携設定
###①mac環境内に作成されたサービス一覧を参照し、サーバのクラスターIPを控える

```
# kubectl get service -n argocd
NAME                    TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
argocd-dex-server       ClusterIP   10.104.157.46    <none>        5556/TCP,5557/TCP,5558/TCP   7d
argocd-metrics          ClusterIP   10.108.131.14    <none>        8082/TCP                     7d
argocd-redis            ClusterIP   10.96.129.252    <none>        6379/TCP                     7d
argocd-repo-server      ClusterIP   10.110.74.232    <none>        8081/TCP,8084/TCP            7d
argocd-server           ClusterIP   10.97.205.169    <none>        80/TCP,443/TCP               7d
argocd-server-metrics   ClusterIP   10.106.234.117   <none>        8083/TCP                     7d
```

###②Port Fowardingする
Port Fowardingがわからない場合は参考資料を参照してください。
argocdのデータを中継することを指します。

```
# kubectl port-forward svc/argocd-server -n argocd 8080:443
```


###③ブラウザへargocdサーバ情報を入力し、画面が表示されることを確認する

`https://localhost:8080`
![スクリーンショット 2021-11-17 11.56.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/430110/50dde297-6c8a-b0ab-cafb-92b6818c81c6.png)

※画像はGITHUB連携によるログインを可能にしたargocdの為、argocdのログイン画面にGITHUBでログインが可能となるボタンが存在します。
設定する前段階では、存在しないので注意です。

###④パスワードを出力し、ログイン
初期パスワードからのログインについては以下にまとめたので、参照してください。
[argocdへログインできなかった時の対処法](https://qiita.com/none_/items/9f8b5f4617ed33ec20a1)

###⑤SSO連携の為にconfigmapを編集する
詳しくは参考資料を参照してください。

```
# kubectl edit configmap argocd-cm -n argocd
```


##参考資料
[ArgoCDのGithubとのSSO連携設定](https://qiita.com/ttr_tkmkb/items/d3cb0625e0df874a7157)
[「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](https://wa3.i-3-i.info/word12664.html)