OmniAICreator/Qiita-1.07M huggingface dataset:
【Project Euler】Problem 78: コインの分割

* 本記事は[ProjectEuler](https://projecteuler.net/about)の「100番以下の問題の説明は記載可能」という規定に基づいて回答のヒントが書かれていますので、自分である程度考えてみてから読まれることをお勧めします。

### 問題 78.コインの分割

原文 [Problem 78: Coin partitions](https://projecteuler.net/problem=78)

**問題の要約：コイン$n$個を分割する方法の数$p(n)$が$10^6$の倍数になる最小の$n$を求めよ**

分割問題3部作の最後です。「[Problem 76: 整数の分割](https://qiita.com/masa0599/items/4382a49e4a28799f7f6f)」と同じなのですが数が全然大きいのでまた違ったアプローチが必要になります。とても100番以下の問題とは思えませんね。

とりあえずProblem 76で紹介した**npartition**で単純に探して見ます。5分以上かかりますが答えは見つかります。

```python 
from sympy.ntheory import npartitions
from itertools import count
for n in count():
  p = npartitions(n)
  if p % 10**6 == 0:
    break
print(f"Answer: {n}")
```

これを超える方法なんてあるのと思いますが探すとあるんですね。「[分割数(Wikipedia)](https://ja.wikipedia.org/wiki/%E5%88%86%E5%89%B2%E6%95%B0#%E5%88%86%E5%89%B2%E6%95%B0%E3%81%AE%E6%AF%8D%E5%87%BD%E6%95%B0)」の「分割数の母函数」セクションで以下のような漸化式が紹介されてます。

```math
\begin{align}
&p(k) = p(k − 1) + p(k − 2) − p(k - 5) − p(k − 7) + p(k − 12) + p(k − 15) − p(k − 22) − ...  \\
&ここで1,2,5,7,12,15,22 は\frac{n(3n − 1)}{3} の形の一般五角数でnの符号が交互(+/-)\\
&また各項の符号は +, +, −, −, +, +, ... と続く
\end{align}
```
これをPythonで実装したのがこちらです。

```python 
from itertools import count
from functools import lru_cache
@lru_cache(maxsize=None)
def pentnum(m):
  k = [1, -1][m%2] * (m // 2 + 1)
  return (k * (3 * k - 1)) // 2

p = [1]
for n in count(1):
  p.append(0)
  for m in count(0):
    penta = pentnum(m)
    if penta > n: break
    p[n] += [1,1,-1,-1][m%4] * p[n - penta]
    p[n] %= 10**6
  if (p[n] == 0): break
print(f"Answer : {n}")
```

（開発環境：Google Colab）
【AWS】CodePipelineのチュートリアルをサクッとやる

# CodePipeline のチュートリアル

使うことになったので早速チュートリアルをやる
[公式手順](https://docs.aws.amazon.com/ja_jp/codepipeline/latest/userguide/tutorials-simple-codecommit.html)

## チュートリアルの流れ

1. CodeCommitのリポジトリのmasterブランチへのプッシュを行うと
2. CodePipelineによってCodeDeployが実行されて
3. EC2にデプロイを実行する
4. デプロイ完了したら、Congratulationsのページが表示される

## 手順

### 1. IAM作成

- name : CICDtest
- role : 
  - AWSCodePipeline_FullAccess
  - AWSCodeCommit_PoweUser

### 2. リポジトリ作成 & クローン

### リポジトリ作成

- name : myrepo

### IAM設定

- パブリックキー登録

CICDtestユーザの`認証情報`に
ローカルサーバのSSH公開鍵を登録

- アクセスキー発行

`アクセスキーの作成`でキー作成

`$ aws configure` コマンドでキー情報を指定

- configファイル作成

ここが特殊で、`.ssh/`ディレクトリに`config`というファイルを作成して.
パーミッションを600にする必要があった

```:config
Host git-codecommit.*.amazonaws.com
User アクセスキーID
IdentityFile ~/.ssh/id_rsa(公開鍵と対になる秘密鍵)
```

```shell
[user@host .ssh]$ ls -lA
合計 20
-rw-------. 1 user user 1550 12月  6 10:14 authorized_keys
-rw-------. 1 user user   89  2月  8 16:08 config
-r--------. 1 user user 2602 12月  5 00:38 id_rsa
-rw-r--r--. 1 user user  570 12月  5 00:38 id_rsa.pub
-rw-r--r--. 1 user user 2886  2月  8 16:09 known_hosts
```

### clone実行

```shell
$ git clone ssh://git-codecommit.us-west-2.amazonaws.com/v1/repos/myrepo
```

## 3. サンプルファイルDL & push

- DL

```shell
$ cd myrepo
$ wget https://docs.aws.amazon.com/ja_jp/codepipeline/latest/userguide/samples/SampleApp_Linux.zip
$ unzip SampleApp_Linux.zip
$ mv SampleApp_linux.zip ../
```

- push

```shell
$ git add -A
$ git commit -m "Add sample application files"
$ git push
```

## 4. EC2作成、CodeDeployエージェントインストール

### ロール作成

作成するEC2インスタンスにインスタンスロールをアタッチして、
CodeDeployを実行できるようにしたいので、
まずインスタンスロールを作成する

- name : EC2InstanceRole
- policy : AmazonEC2RoleforCodeDeploy (CodeDeployで検索)

### EC2インスタンス作成

- name : EC2Instance
- AMI : AmazonLinux
- 自動割り当てパブリックIP : 有効
- IAM : EC2InstanceRoleさっき作ったやつ
- 高度
  - ユーザーデータ : ↓

```
#!/bin/bash
yum -y update
yum install -y ruby
yum install -y aws-cli
cd /home/ec2-user
wget https://aws-codedeploy-us-east-2.s3.us-east-2.amazonaws.com/latest/install
chmod +x ./install
./install auto
```

- セキュリティグループ : HTTP(80)だけ開いてたらOK
- タグ
    - name : EC2Instance

## 5. CodeDeploy設定

### CodeDeploy用のロール作成

- name : CodeDeployRole
- policy : ユースケースでCodeDeployを選ぶと自動で選択されている

### CodeDeploy Application の作成

- name : demo-application
- プラットフォーム : ec2/オンプレミス

### CodeDeploy DeployGroup の作成

- name : demo-deploy-group
- role : さっき作ったやつ
- type : インプレース
- environment  : EC2インスタンス
  - キー: 
    - name:EC2Instance(EC2インスタンスの名前)
- deploy : CodeDeployDefault.OneAtATime
- LB : 無効化

## 6. Pipeline作成

- name : MyPipeline
- ロール : 新しい
  - name : MyPipelineRole
- ソース : CodeCommit
  - reponame : myrepo
  - branch : master
- ビルド : スキップ
- デプロイ :
  - ソース : CodeDeploy
    - ロケーション : 東京
    - アプリケーション名 : demo-application (さっき作ったやつ)
    - デプロイグループ : demo-deploy-group (さっき作ったやつ)

実行するとデプロイ開始される
うまくいってたら成功表示が出る

## 7. 確認

作成したEC2のパブリックIPにHTTPアクセスすると、
アプリがデプロイされてCongraturationsのページが表示される

## 感想

一番難しかったのがCodeCommitのSSHを使ったリポジトリのクローンでした、、、
むしろそれくらいPipelineの構築が単純明快でよかった
【Project Euler】Problem 77: 整数を素数に分割

* 本記事は[ProjectEuler](https://projecteuler.net/about)の「100番以下の問題の説明は記載可能」という規定に基づいて回答のヒントが書かれていますので、自分である程度考えてみてから読まれることをお勧めします。

(追記) sagemathのプログラムを追加しました。

### 問題 77. 整数を素数に分割

原文 [Problem 77: Prime summations](https://projecteuler.net/problem=77)

**問題の要約：自然数$n$を素数の和で表す組み合わせ初めて5000を超える$n$求めよ**

今回は素数の和と言うことでとりあえず再帰関数で全探索しました。値があまり大きくないので何とか1分ルールはクリア。

```python
from sympy import primerange
from copy import copy

def cutNumPrimes(L, n):
  count = 0
  for pr in Primes:
    if len(L) > 0 and pr < L[-1]: continue  # List should ascending order
    L1 = copy(L)
    L1.append(pr)
    rem = n - pr  # remaining numbers
    if rem > 0:
      count += cutNumPrimes(L1,rem) # search more
    elif rem == 0: 
      count += 1
  return count

Nmax = 100
Primes = list(primerange(1,Nmax+1))
for n in range(2,Nmax+1):
  countSum = cutNumPrimes([],n)
  if countSum > 5000:
    break
print(f"Answer : {n}, {countSum}")
```

その後いろいろ探して見たところこの数列はオンライン整数列大辞典の[A000607](http://oeis.org/A000607)に以下のようなプログラムを発見しました。かなり速いです。

```python 
from sympy import primefactors
l = [1, 0]
for n in range(2, 101):
  l.append(sum(sum(primefactors(k)) * l[n - k] for k in range(1, n + 1)) // n)
print(l)
```

これはどういうアルゴリズムなのか調べた結果なんとか見つけたのが、「[Prime Partition(Wolfram MathWorld)](https://mathworld.wolfram.com/PrimePartition.html)とそこから参照されている「[Euler Transform(Wolfram MathWorld)](https://mathworld.wolfram.com/EulerTransform.html)」の以下の式と説明。これを実装したのが上のプログラムかなと思いますが、下の式の意味は私の知識レベルでは理解できませんでした。誰か分かる方がいたらコメント頂ければ幸いです。

```math
 b_n=\frac{1}{n}[c_n+\sum_{k=1}^{n-1}c_k b_{n-k}]
```

> if $a_n$=1 for n prime and $a_n$=0 for n composite, then $b_n$ is **the number of partitions of n into prime parts** (Sloane and Plouffe 1995, p. 21). 

（開発環境：Google Colab）

### sagemathのPartitionsを使う

sagemathのPartitionsにはparts_inというパラメータがあり使うパーツを指定できます。ここに素数のリストをprime_rangeで指定すると簡単に求まります。

```python 
n = 2
while Partitions(n, parts_in=prime_range(n + 1)).cardinality() < 5000:
    n += 1
print(n)
```

（開発環境：CoCalc）
【Project Euler】Problem 76: 整数の分割

---
* 本記事は[ProjectEuler](https://projecteuler.net/about)の「100番以下の問題の説明は記載可能」という規定に基づいて回答のヒントが書かれていますので、自分である程度考えてみてから読まれることをお勧めします。

### 問題 76. 整数の分割

原文 [Problem 76: Counting summations](https://projecteuler.net/problem=76)

**問題の要約：100を自然数の和で何通りの組み合わせで表せるかを求めよ**

### 分割数の漸化式
これは有名な「[自然数の分割（Wikipedia）](https://ja.wikipedia.org/wiki/%E8%87%AA%E7%84%B6%E6%95%B0%E3%81%AE%E5%88%86%E5%89%B2)」の問題ですね。たぶんこれだけで本が書けるくらい多くの話題がありそうですが、こちらの「[分割数の意味と性質・ヤング図形の活躍](https://manabitimes.jp/math/888)」が割と簡潔にまとまっているかなと思います。ここで以下の漸化式が出ています。

```math 
p_k(n)=p_k(n−k)+p_{k−1}(n−1)
```
### 再帰関数での実装

これをもとにして書いたのがこちら、再帰関数で繰り返しが多いので**lru_cache**を使っています。

```python 
from functools import lru_cache
@lru_cache(maxsize=None)
def npart(n, k):
  if n == 0 or k==1: return 1
  ret = npart(n, k-1)
  if n >= k:
    ret += npart(n-k, k)
  return ret
n = 100
print(f"Answer: {npart(n,n)-1}") 
```
### 配列を使った実装

再帰関数を使わずに配列を使って実装したのがこちら。かなりシンプルになってます。

```python 
def npart(n):
  p = [1]+[0]*n
  for i in range(1, n+1):
    for j in range(i, n+1):
      p[j] += p[j-i]
  return p[n]
 
print(f"Answer: {npart(100)-1}")
```

### sympyの関数（partitions, npartitions）

これだけ有名な問題なのでさすがに**sympy**にありますね。まずは分割の数をすべてリストしてくれる**partitions**

```python 
from sympy.utilities.iterables import partitions
n = 4
print(list(partitions(n)))
# [{4: 1}, {3: 1, 1: 1}, {2: 2}, {2: 1, 1: 2}, {1: 4}]
```

そしてまさに分割数を返す関数**partition**。あっけなく答えが求まります。

```python 
from sympy import partition
print(f"Answer: {partition(100)-1}"))
```

（開発環境：Google Colab）
SSH公開鍵作成コマンド

##はじめに
Linux系OSでは、パスワードや鍵認証によるユーザログインを行います。
今回は、ユーザログイン用の鍵認証の設定方法を書きます。


##公開鍵作成

※前提として、
後から権限の変更がないように、
鍵認証を利用したいユーザで操作を行うことをオススメします。

ユーザのディレクトリに移動します。

```
cd /home/ユーザ名/
```

カレントディレクトリを確認します

```
ls -la
```

.sshディレクトリがない場合は作成をします

```
mkdir .ssh
```

```
chmod 700 /home/ユーザ名/.ssh
```

キーペアを作成します。
デフォルトは2048なので、4096を指定しています。

```
ssh-keygen -t rsa -b 4096
```

キーペアが作成されると、
.sshディレクトリの中に下記ファイルが作成されます。
id_rsa
id_rsa.pub

キーを登録します。

```
cat id_rsa.pub >> authorized_keys
```

```
chmod 600 authorized_keys
```

ローカルへid_rsaの中身を持ち出し、
.pemで保存します。（コピー等）

```
cat id_rsa
```

ログインができたら、作成した鍵を削除します。


#ログイン・鍵作成ができない場合

①ディレクトリのパーミッション間違い
②.sshディレクトリの所有者違い
以下で変更

```
chown ユーザ名:ユーザ名 .ssh
```

③/etc/ssh/sshd_configのPubkeyAuthenticationがnoになっている
→yesに変更する

再起動

```
systemctl restart sshd
```

④下記エラーメッセージが表示されて鍵（キーペア）が作成できない
`/root/.ssh/id_rsa already exists.
`

↓作成時に鍵の保存場所を指定する

```
/home/ユーザ名/.ssh/id_rsa
```
Oculus Quest開発用Desktopの作成手順をWindowsインストールから記す

# はじめに
これは，研究室の後輩向けにWindowsPCのOS入れからOculus Quest開発におけるデバッグ環境構築までの手順を記したものです．

#手順
## WindowsOSを入れる
研究室のPCはクリーンインストールです．クリーンインストールをする際，よく躓くのがPCのパーテーションについてのトラブルです．基本は[このサイト](https://www.pc-jozu.com/mame/windows-10-clean-install/)を見てやればできると思います．
##必要なアプリケーションを入れる
Oculus Quest開発用端末を作るとき，私が入れるアプリケーションは以下のものになります．
* [Oculus](https://support.oculus.com/articles/getting-started/getting-started-with-rift-s/install-oculus-app-pc-rift-s-setup/?locale=ja_JP)
* [Unity](https://unity.com/ja)
* [Android Studio](https://developer.android.com/studio/install?hl=ja)
* [Oculus ADB Drivers](https://developer.oculus.com/downloads/package/oculus-adb-drivers/?locale=ja_JP)

Unityは[こちらを参照](https://qiita.com/ciao_kaokawa/items/dea75f584a4dfa84ec1f)して適切なバージョンを入れてください．
またこの時，Android debug ToolsとVisual Studio Communityを入れ忘れないようにしてください．
OculusはOculus Linkをする際に，Unityは言わずもがな，Android Studioはapkファイル関連のエラー用，Oculus ADB Driversは一応です．

## コマンドプロントにadbを通す
Oculus QuestはAndroidなので開発するのにadb(Android Debug Bridge)というものが必要になります．これは，[このサイト](https://aaaaa.hateblo.jp/entry/2017/05/05/090945)を参照すると設定できると思います．
設定できたら，PCにOculus Questを接続しコマンドプロントで

```コマンドプロント
$ adb devices
```
と入力してみてデバイスが認識されているか確認しましょう．
Oculus QuestをPCに接続したとき，HMD内にPCを信頼するかのポップアップが出てきます．
これを許可し忘れると動作しません．
また，研究室のHMDはすべて開発者モードがオンになっているはずです．もしオフになっていたら[ここ](https://holoeyes.zendesk.com/hc/ja/articles/1500001888282-Oculus-Quest-Oculus-Quest-2-%E3%82%92%E9%96%8B%E7%99%BA%E8%80%85%E3%83%A2%E3%83%BC%E3%83%89%E3%81%AB%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B%E3%81%AB%E3%81%AF%E3%81%A9%E3%81%86%E3%81%97%E3%81%9F%E3%82%89%E8%89%AF%E3%81%84%E3%81%A7%E3%81%99%E3%81%8B-)を見てオンにしてください．

# 最後に
お疲れ様です．これがWindowsPCをクリーンインストールしてOculus Quest開発用端末にするまでです．
できそうであればアプリを作ってみてください．
Flutterをバージョンアップしたら'accentColor' is deprecated and shouldn't be used. Use colorScheme.secondary instead.

#`main.dart`で定義しているaccentColorがdeprecatedに
![スクリーンショット 2022-02-08 20.16.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/108cba66-1a42-3998-534e-d96d7a9ef1ee.png)

#VSCodeの機能で簡単に解決！
`Quick Fix＞Migrate to 'ColorScheme.secondary'`を選択

![スクリーンショット 2022-02-08 20.16.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/2eb82094-75ec-9737-0a11-93206caef951.png)

![スクリーンショット 2022-02-08 20.17.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/6947bf91-86fd-e291-a1e9-32551101d814.png)

これで以下のような形になるかと

```dart:main.dart
 child: MaterialApp(
        title: 'Title',
        theme: ThemeData(
          primaryColor: HexColor('F8EEF4'),
          colorScheme:
              ColorScheme.fromSwatch().copyWith(secondary: Colors.yellow[100]),
        ),
```

`Theme.of(context).colorScheme.secondary`で使います:wink:

```dart
style: ElevatedButton.styleFrom(
   primary: Theme.of(context).colorScheme.secondary,
   onPrimary: Colors.black,
   shape: const StadiumBorder(),
 ),
```
You are running `create-react-app` 4.0.3, which is behind the latest release (5.0.0)と出たときの対処法

Reactのアプリを新規作成する際に出たエラーの対処法です。
以下の参考サイトそのままですが（こちらのほうが詳しく書いてくださっています），自分の備忘録として残しておきます。

参考サイト：https://qiita.com/FumioNonaka/items/076af56213afc7e29853

##実行環境

・macOS Catalina 10.15.7

##アプリを作成するコマンド
参考サイト：https://ja.reactjs.org/docs/create-a-new-react-app.html

```
$ npx create-react-app my-app
```

##エラー内容

```
You are running `create-react-app` 4.0.3, which is behind the latest release (5.0.0).

We no longer support global installation of Create React App.

Please remove any global installs with one of the following commands:
- npm uninstall -g create-react-app
- yarn global remove create-react-app

The latest instructions for creating a new app can be found here:
https://create-react-app.dev/docs/getting-started/
```

## 試したコマンド

①まず，エラー文に書いてあるコマンドの1つ目

```
$ npm uninstall -g create-react-app
```
↓ 結果

```
up to date, audited 1 package in 283ms

found 0 vulnerabilities
```
②そして，エラー文に書いてあるコマンドの2つ目

```
$ yarn global remove create-react-app
```
↓ 結果

```
[1/2] 🗑  Removing module create-react-app...
[2/2] 🔨  Regenerating lockfile and installing missing dependencies...
success Uninstalled packages.
✨  Done in 0.47s.
```

③次にキャッシュのクリア（参考サイトより）

```
$ npx clear-npx-cache
```
↓ 結果

```
Need to install the following packages:
  clear-npx-cache
Ok to proceed? (y) y
```
④再度アプリ作成（成功！！）

```
$ npx create-react-app my-app
Need to install the following packages:
  create-react-app
Ok to proceed? (y) y
npm WARN deprecated tar@2.2.2: This version of tar is no longer supported, and will not receive security updates. Please upgrade asap.

Creating a new React app in /Users/kawakami_air/Desktop/my-app.

Installing packages. This might take a couple of minutes.
Installing react, react-dom, and react-scripts with cra-template...


added 1367 packages in 2m

169 packages are looking for funding
  run `npm fund` for details

Initialized a git repository.

Installing template dependencies using npm...
npm WARN deprecated source-map-resolve@0.6.0: See https://github.com/lydell/source-map-resolve#deprecated

added 33 packages in 13s

169 packages are looking for funding
  run `npm fund` for details
Removing template package using npm...


removed 1 package, and audited 1400 packages in 4s

169 packages are looking for funding
  run `npm fund` for details

8 moderate severity vulnerabilities

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.

Created git commit.

Success! Created my-app at /Users/kawakami_air/Desktop/my-app
Inside that directory, you can run several commands:

  npm start
    Starts the development server.

  npm run build
    Bundles the app into static files for production.

  npm test
    Starts the test runner.

  npm run eject
    Removes this tool and copies build dependencies, configuration files
    and scripts into the app directory. If you do this, you can’t go back!

We suggest that you begin by typing:

  cd my-app
  npm start

Happy hacking!
```
【C#】Listから指定条件のデータを取得する方法

#結論
`Where()`を使います。

```C#:例(Listの要素からApexのみを取得する)
List<string> dataList = new() { "Apex", "Valorant", "Fortnite", "PUBG", "APEX", "PSO2NGS", "GTA5"};

const string searchString = "Apex";

//ListからApexという文字列のみを取得する！
var onlyApexList = dataList.Where(x => x == searchString).ToList();

//Apexという文字列の要素がList内に何個あったかを表示！
Console.WriteLine($"{searchString}は{onlyApexList.Count}個あるぞ！！");
//出力：Apexは1個あるぞ！
```

#解説
結論では"Apex"という文字列をListから取得する例を記載しました。実際にListから条件を指定してデータを取得している箇所はここです。

```C#
//ListからApexという文字列のみを取得する！
var onlyApexList = dataList.Where(x => x == searchString).ToList();
```

`x =>`ってなんや...(^ρ^)

```C#:イメージとしてはこんな処理をしてくれています
//ListからApexという文字列のみを取得する！
List<string> onlyApexList = new();

foreach (var x in dataList)
{
    //もし要素がApexという文字列だったら新しいリストに追加する！
    if (x == searchString) onlyApexList.Add(x);
}
```

(´ε｀ )ふぅん...
実際に`Where()`が何をやっているか詳しく知りたい方はリファレンスソースを確認してください！
>[C#リファレンスソース](https://referencesource.microsoft.com/#system.core/system/linq/Enumerable.cs,44b8532e11187695)

#おまけ
Apexっていう文字列を含む要素一覧を取得したい場合

```C#:Apexを含む文字列の要素を取得
List<string> dataList = new() { "Apex", "Valorant", "Fortnite", "PUBG", "APEX", "PSO2NGS", "GTA5"};

const string searchString = "Apex";

//ListからApexという文字列を含む要素を取得する！
var onlyApexList = dataList.Where(x => x.Contains(searchString)).ToList();

//Apexという文字列の要素がList内に何個あったかを表示！
Console.WriteLine($"{searchString}は{onlyApexList.Count}個あるぞ！！");
//出力：Apexは1個あるぞ！
```

大文字小文字関係なくApexという文字列を含む要素一覧を取得したい場合

```C#:大文字小文字関係なくApexを含む文字列の要素を取得
List<string> dataList = new() { "Apex", "Valorant", "Fortnite", "PUBG", "APEX", "PSO2NGS", "GTA5"};

const string searchString = "Apex";

//ListからApexという文字列を含む要素を取得する！
var onlyApexList = dataList.Where(x => x.Contains(searchString, StringComparison.OrdinalIgnoreCase)).ToList();

//Apexという文字列の要素がList内に何個あったかを表示！
Console.WriteLine($"{searchString}は{onlyApexList.Count}個あるぞ！！");
//出力：Apexは2個あるぞ！
```

要素の先頭文字列がPで始まる要素一覧を取得したい場合

```C#:要素の先頭文字列がPで始まる要素一覧を取得
List<string> dataList = new() { "Apex", "Valorant", "Fortnite", "PUBG", "APEX", "PSO2NGS", "GTA5"};

const string searchString = "P";

//Listから先頭文字列がPで始まる要素を取得する！
var onlyApexList = dataList.Where(x => x.StartsWith(searchString)).ToList();

//要素の先頭文字列がPで始まる要素がList内に何個あったかを表示！
Console.WriteLine($"先頭文字列が{searchString}から始まる要素は{onlyApexList.Count}個あるぞ！！");
//出力：先頭文字列がPから始まる要素は2個あるぞ！！
```

要素の末尾がxで終わる要素一覧を取得したい場合

```C#:要素の末尾がxで終わる要素一覧を取得
List<string> dataList = new() { "Apex", "Valorant", "Fortnite", "PUBG", "APEX", "PSO2NGS", "GTA5"};

const string searchString = "x";

//Listから末尾がxで終わる要素を取得する！
var onlyApexList = dataList.Where(x => x.EndsWith(searchString)).ToList();

//要素の末尾がxで終わる要素がList内に何個あったかを表示！
Console.WriteLine($"末尾が{searchString}で終わる要素は{onlyApexList.Count}個あるぞ！！");
//出力：末尾がxで終わる要素は1個あるぞ！！
```

以上です。
Django models to DataFrame to csv

```python

from datetime import datetime
import numpy

from django.core.management import BaseCommand
from django.db.models.fields import DateTimeField, BooleanField

from model import YourModel

import pandas as pd


# Usage
ExportModel(YourModel, ForeignKey)


class ExportModel:

    def __init__(self, model, key):
        self.target_model = model
        self.key = key
        self.target_key_value = {"key":key}

    def exec(self):
        if self._target_table_check_exists_key():
            self._target_model_export_data()

    def _target_table_check_exists_key(self):
        self.target_model_filterd_key_qs = self.target_model.objects.filter(**self.target_key_value)
        if len(self.target_model_filterd_key_qs) > 0:
            return True
        else:
            return False

    def _target_model_export_data(self):
        df = pd.DataFrame.from_records(self.target_model_filterd_key_qs.values())

        for col in self.target_model._meta.fields:
            if col.__class__ == DateTimeField:
                df[col.name] = pd.to_datetime(df[col.name])
                df[col.name] = df[col.name].dt.strftime('%Y-%m-%d %H:%M:%S')

            if col.__class__ == BooleanField:
                df[col.name] = df[col.name].replace(False, "0")
                df[col.name] = df[col.name].replace(True, "1")

        # ほとんどのFiledsのNoneはNAで抽出できる
        df = df.replace(pd.NA, "NULL")
        # DateTimeFieldsのNullはNaN
        df = df.replace(numpy.NaN, "NULL")

        csv_file_name = f"""{self.key}_{self.target_model.__name__}_deleted_{datetime.now().strftime("%Y-%m-%d_%H:%M")}.csv"""
        df.to_csv(csv_file_name, index=False)

```

#### 概要
 - DjangoのモデルからDataFrameに変換して、Sequelとかにそのまま読み込ませれるような形式でCSVに出力するサンプルコードです。

#### 学び
 - 多少（1~2割ぐらい）修正していますが、実際に書いたコードをほぼそのまま載せています。
 - 手前味噌ですが、ある程度良いコード？は抽象化されているからそのまま載せてもほぼほぼ問題ない可能性が高いのかなとか思ったりしました。
GCP Professional Data Engineer受験記 (2022年2月)

# はじめに
GCPの資格であるProfessional Data Engineer認定資格に合格したので、いろいろ書きます。

# 学習前のスペック
- エンジニア歴2年弱
- (AWS)データエンジニア歴1.5年
- 試験範囲のGCPリソース（BigQueryとか）の使用経験はゼロ

**データエンジニアリングの基礎知識はあるが、GCPやMLの経験はほぼゼロ**という感じです


# やったこと
- [Coursera: 公式動画教材](https://www.coursera.org/professional-certificates/gcp-data-engineering-jp)
- [Udemy: 模擬問題](https://www.udemy.com/course/gcp-pde-test-ja/)
- [(書籍: Google Cloudではじめる実践データエンジニアリング入門)](https://www.amazon.co.jp/dp/429711948X)

### Coursera
まず、基礎知識の学習にこれを使いました。
主に英語の動画教材ですが、日本語字幕を出せるので、英語弱者（僕）でもどうにかなります。

Qwiklabs（日本語）を用いたハンズオンも搭載されているので、手を動かすこともできます。

また、**各コースの修了想定時間を合計すると61時間**です。

### Udemy
次に、Udemyの模擬問題を解きました。
解説にて、選択肢それぞれの正解/不正解の理由が書かれているので、とても勉強になります。

ちなみに、初回テストの結果は、1個目が約55%、2個目が約45%でした。

### 書籍
模擬問題で分からなかった部分をパラシュート勉強法するのに使いました。

**Courseraだけでは試験範囲を全てカバーできない**ので、こちらも全て読むことをオススメします。
（僕は数十ページしか使わなかったので、ギリギリでした）

# アドバイス
試験内容は、「データ関連のGCPリソースの知識があるか」だけでなく、「**使用経験がある上で、適切な思考・判断ができるか**」も測る内容だと感じました。
実際、**ラッキー問題は極一部です**。

### 極一部のラッキー問題例
**回答欄がGCPリソース名のみ**

概要さえ知っていれば解けるやつです

### よくある問題例
**回答欄にあるGCPリソース名が全て同じで、細かいオプション・導入方法などが違う**

手を動かした経験が無いと解けないやつです

***

↑の理由により、学習目的でなく合格優先の方でも、（時間があるなら）手を動かすことをオススメします。

また、MLの問題も沢山出るので、「データエンジニアだから管轄外だしやらなくていいか…」と思わない方が良いです。
試験で痛い目に遭いました。
（ギリギリ何とかなりましたが）

***
あと、この試験に限った話では無いですが、なるべくテストセンターで受けることをオススメします。
部屋を片付けているのに、「片付けてください」と指示されて凹む可能性があります。
[過去記事](https://qiita.com/iwakiriK/items/fca0172edd9649420c96#%E6%9C%BA%E9%83%A8%E5%B1%8B%E3%81%AE%E7%89%87%E4%BB%98%E3%81%91)

# さいごに

手応えではギリ6割ぐらいでしたが、無事合格できました。

試験では、知らない問題に沢山遭遇することになると思います。
自信を無くしてしまうかもしれませんが、諦めずに最後の1分まで足掻くことをオススメします。

それでは、受験予定の方々の検討をお祈りします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132702/65b8e782-7e4f-9a46-e2c4-a63d8fee8ad3.png)
[合格証](https://scl.io/56PHrGO)
初心者アレイについて知識

#アレイについて文法は

```ruby:qiita.rb
　　　  int [] array = {};
        int [] array1 = new int [3];//３はこのアレイの長です
        int [] array2 = new int[] {1,2,3};
```

#間違易いエラーは
 arrayindexoutof bounds exception アレイ読み出しの範囲がこのアレイの範囲を超えてる場合発生したエラー例えば

```ruby:qiita.rb
int[] array = new int[5];
int boom = array[10]; // ここに異常がありです
```



#アレイコンテンツの表示文法:
```ruby:qiita.rb
for (int i = 0; i < array.length; i++) {
        	System.out.println(array[i]);	
		}
```
#array tools：
１．アレイのコンテンツをフォマード表示：

```ruby:qiita.rb
Arrays.toString();  //[1,2,3]このように表示アレイコンテンツ
        int[] a = {9, 8, 7, 2, 3, 4, 1, 0, 6, 5};
```
２．アレイの配列：

```ruby:qiita.rb
Arrays.sort(a);//アレイの配列　「0 1 2 3 4 5 6 7 8 9」
```
３．アレイの配列（順序あり場合）

```ruby:qiita.rb
String[] intArray = new String[]{"a","b","c","d","e","f","g","h","i","j",};
		int positon = Arrays.binarySearch(intArray, "d");
		System.out.println("position is:"+positon);
　　//順序がある条件の上、コンテンツはアレイの位置を探す
```
４．アレイの配列（順序なし場合）

```ruby:qiita.rb
for (int i = 0; i < intArray.length; i++) { //無順序の上　コンテンツの位置を探すの場合
			int key = 1;//位置を探したいの数
			if (key == array[i]) {
				System.out.println(i);
			}　
```
５．アレイのコピー

```ruby:qiita.rb
int newarray[] = Arrays.copyOf(array, 3);//３はどうこからコピーしたいの位置です
```

#終わり
gcloudでconfigを追加して切り替える

# やること
`gcloud config`を使用して、新しい`config`の追加および切り替えを行います。
前提として`Cloud SDK`がインストールされていることとします。（インストール方法は[こちら](https://cloud.google.com/sdk/docs/install)をご覧ください。）

# 環境
```
$ gcloud -v
Google Cloud SDK 371.0.0
beta 2022.01.28
bq 2.0.73
core 2022.01.28
gsutil 5.6
kubectl 1.17.17
minikube 1.19.0
skaffold 1.21.0
```
# 実践

## configの追加
まずは追加する`config`の名前をつけることから始めます。実際のプロジェクトとの紐付けは後ほど行いますので、ここではわかりやすい名前をつけることをお勧めします。（例えば`prd_app`や、`stg_app`など、環境とサービス名を合わせるといいかもしれません。）
ここでは例ですので`app1`とします。
([公式ページ](https://cloud.google.com/sdk/gcloud/reference/config/configurations/create))

```
$ gcloud config configurations create app1
Created [app1].
Activated [app1].
```
念のため、作成した設定が存在しているかを確認します。

```
NAME                IS_ACTIVE  ACCOUNT               PROJECT                   COMPUTE_DEFAULT_ZONE  COMPUTE_DEFAULT_REGION
default             False      hoge@example.com
app1                True
```
上記のようになるかと思います。（`default`は元からある設定のため、表示内容は人によって少々異なります。）
見ての通り`app1`の`IS_ACTIVE`が`True`となり、`ACCOUNT`以降が空欄（未設定）であることがわかります。
それでは以降で`ACCOUNT`以降を設定していきます。

## 追加したconfigに情報を付与していく
先ほど追加した`app1`に、必要な設定を追加していきます。
以降のコマンドは、前述した`IS_ACTIVE`が`True`となっている`config`に対して適用されます。
必ず対象となる`config`がアクティブになっていることを確認してから行いましょう。

設定内容は多岐にわたりますが、最低限設定しておきたい、上記の`ACCOUNT`以降を対象とします。
各設定値に関しては[公式ページ](https://cloud.google.com/sdk/gcloud/reference/config/set)をご確認ください。

### プロジェクトの設定
設定するプロジェクトのIDを指定します。対象のプロジェクトのトップページから「プロジェクト情報」内にある「プロジェクトID」です。

```
$ gcloud config set project app-project
Updated property [core/project].
```

### アカウントの設定
自分のメールアドレスを設定します。

```
$ gcloud config set account hoge@example.com
Updated property [core/account].
```

### デフォルトゾーンの設定
デフォルトゾーンを指定します。例では`asia-northeast1-a`を設定していますが適宜ご自分の使用する地域に修正してください。（[こちら](https://cloud.google.com/compute/docs/regions-zones#available)で使用できるゾーン・リージョンを確認できます。)

```
$ gcloud config set compute/zone asia-northeast1-a        
Updated property [compute/zone].
```

### デフォルトリージョンの設定
デフォルトゾーンを指定します。例では`asia-northeast1`を設定していますが適宜ご自分の使用する地域に修正してください。

```
$ gcloud config set compute/region asia-northeast1
Updated property [compute/region].
```

### 設定後の確認
ここまでで設定したいものは設定できたと思いますので、設定内容を確認してみましょう。

```
NAME                IS_ACTIVE  ACCOUNT               PROJECT                   COMPUTE_DEFAULT_ZONE  COMPUTE_DEFAULT_REGION
default             False      hoge@example.com
app1                True       hoge@example.com      app-project               asia-northeast1-a     asia-northeast1
```

## configの切り替え
`activate`を使用することで指定した`config`を有効化できます。

```
$ gcloud config configurations activate app1
```

## (おまけ)configの削除
不要になった`config`は削除してしまいましょう。（[公式ページ](https://cloud.google.com/sdk/gcloud/reference/config/configurations/delete)）

```
$ gcloud config configurations delete app1
```

# 終わりに
ごく基本的な設定に留まりますが、上記で最低限のことは設定できると思います。
それでは素敵なGCPライフを！
コマンドでAndoirdエミュレータ起動＆APKインストール

## エミューレータを起動させる
#### 起動できるエミューレータの一覧を表示

```
~/Library/Android/sdk/emulator/emulator -list-avds
```

#### エミューレータを起動

```
~/Library/Android/sdk/emulator/emulator @Pixel_5_API_31
```



## APKのインストール


#### APKをインストールできる端末一覧を表示

```
adb devices -l
```

#### APKをインストール
```
adb -s emulator-xxx install xxx.apk
```
Python standalone アプリに認証機能を入れたいメモ

## 背景

Python アプリを pyinstaller あたりで配布したい.
ソースコードは開示したくない. アクセス制限(ライセンス認証)を入れたい.

## Possible way

まず, pyinstaller には python code を暗号化(16 文字のパスコード)する機能がありますので, これを利用するとよいでしょう.

https://pyinstaller.readthedocs.io/en/stable/usage.html#encrypting-python-bytecode

PyArmor などで難読化を先に行っておくとより安心でしょうか

## アクセス制限

web サイトログインのように, アプリ起動時にチェックでしょうか. 

インターネット接続を許すなら 2FA ログインとか

https://www.section.io/engineering-education/implementing-totp-2fa-using-flask/

## 注意点

3rd party module のライセンスを確認する(GPL なのがあったらソースコード開示義務がある)

## TODO

* [ ] decrypt された Python コードは, Windows だとセキュアメモリ領域(他プロセスから見えない)に展開されるのかな?
* [ ] USB ドングルとかライセンスキーみたいなように .exe の起動自体(?)に認証がいるようにする方法はあるかな?
【Rails】where.notを連結するしないでクエリが異なる

下２つは同じクエリを吐き出すと勘違いしていたので備忘録。

```ruby
where.not(tag: '', user_id: 1)

where.not(tag: '').where.not(user_id: 1)
```

##where.notを複数連結

画像左

```ruby
Post.where.not(tag: "Ruby").where.not(user_id: 1)
=> SELECT `posts`.* FROM `posts` WHERE `posts`.`tag` != 'Ruby' AND `posts`.`user_id` != 1
```


##連結しない
画像右

```ruby
Post.where.not(tag: "Ruby", user_id: 1)
=> SELECT `posts`.* FROM `posts` WHERE NOT (`posts`.`tag` = 'Ruby' AND `posts`.`user_id` = 1)
```


![math.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1990648/b2170078-f771-fa3c-78da-24e382d12c32.jpeg)


##参考

https://railsdoc.com/page/model_not
kubernetesでpodを再起動しても使われる imageが更新されない場合に試すこと


## 問題

開発環境の話です。
同じイメージタグでイメージを更新しつつ、podに反映したいことってありますよね？
が、latestタグ以外の場合、podを再起動(``kubectl delete pod``)しても反映されないことがあります。というかほぼされません。


## 解決

答えはここに。

> Loading an Image Into Your Cluster
https://kind.sigs.k8s.io/docs/user/quick-start/#loading-an-image-into-your-cluster

``latest``タグ以外の時は``imagePullPolicy: IfNotPresent``なので、既に起動済みのイメージの場合、更新されないわけですな。

そんな時は、``imagePullPolicy: Always`` をそっと添えてあげれば解決です。

こんな感じ

```yml
.
.
  spec:
       containers:
       - name: xxxx-container
         image: xxxx-container.foo.bar.repository:dev
         imagePullPolicy: Always
.
.
```


トレーサビリティーのためにも、CD回すためにも、``production``ならば毎回タグを更新すると思いますが、開発環境でハマりやすい問題ということで。
ご参考まで。
Google Calendar API で作成した全日イベントが、Android版Google カレンダーアプリでのみ表示されない

## 発生したこと
Google Calendar APIを使用して、全日イベントを作成した時

- Android版のカレンダーアプリでのみ、作成したイベントが表示されない
- Androidでも、アイコンがGoogleカラーになる前の、(日めくりカレンダー形式アイコンの)旧版カレンダーアプリでは表示される
- Android以外のプラットフォーム(ブラウザ・iOS版アプリなど)では、問題なく表示される

## 原因
例えば１日のみの全日イベント場合において、``Event.Start.Date``と``Event.End.Date``に同じ日付をセットしていた。
正しくは、**``Event.Start.Date``には開始日をセットし、``Event.End.Date``には、終了日＋１をセットする(ようだ…)**
[公式ドキュメント](https://developers.google.com/calendar/api/v3/reference/events/insert)には、そんなことは書かれていない気がするが…
##### 例：全日イベントが２０２２年２月１日(のみ)のとき
```csharp:C#
var createdEvent = service.Events.Insert(new Event
{
	Summary = "タイトル",
	Start = new EventDateTime() { Date = "2022-02-01") },
	End = new EventDateTime() { Date = "2022-02-02") }, // <-- 2022-02-01ではない
	Description = "説明",
}, calendarId);
```

## ひとこと
プラットフォームによって、しかもバージョンアップで動きを変えるのはやめて欲しい…
EMLファイル Gmail インポート - EMLをGmailに一度にバッチ変換

<p>Windows Liveメール、Windowsメール、Mozilla Thunderbird、Outlook Expressなどの多くの電子メールアプリケーションは、EMLファイル形式をサポートしています。これにより、すべての受信トレイの内容を1つの便利な場所に保持できます。 EMLファイルは、外部ストレージデバイスを使用して、簡単に表示して他のマシンに転送できます。ユーザーは、EMLファイルを電子メールクライアントのフォルダーにドラッグアンドドロップして、そこから開くことにより、すばやくアクセスできます。一方、GmailなどのWebベースの電子メールクライアントでEMLデータを使用するには、ユーザーは最初にEMLをGmailにインポートする必要があります。ユーザーはGmailを使用して、GmailアカウントをMicrosoft Outlookなどの電子メールサービスプロバイダーに接続することにより、EMLファイルを受信トレイにインポートできます。</p>
<p>設定手順に予想以上の時間がかかり、忍耐が必要になる可能性があります。手動セットアップ方法では、ユーザー側の技術的専門知識を使用する必要があります。別の方法として、顧客はプロの自動EMLファイルコンバーターを利用できます。これは、ユーザー側で技術的なスキルを使用する必要はありません。</p>
<p>変換手順全体に進む前に、EMLファイルをGmailにインポートする理由のいくつかを検討してください。</p>
<h2>さまざまな理由でEMLをGmailにインポートする</h2>
<p>EMLファイルをGmailアカウントにインポートする最も説得力のある理由のリストをまとめました。</p>
<p>Gmailは、インターネット上で運営されている無料のメールサービスプロバイダーです。</p>
<p>Gmailは、消費者の間で最も人気があり、広く使用されているメールサービスプロバイダーの1つであり、多くの言語で利用できます。</p>
<p>スムーズでユーザーフレンドリーなグラフィカルユーザーインターフェイス（GUI）を備えています。</p>
<p>これはより安全なプラットフォームであり、すべてのEMLデータはこのプラットフォームで安全に保たれます。</p>
<p>これらは、人々がEMLファイルをGmailアカウントにインポートすることを望む理由のほんの一握りです。次に、EMLファイルをGmailにインポートするより専門的な方法に進みます。これにより、以前の方法よりも迅速で信頼性の高いデータ変換プロセスが可能になります。</p>
<h2>EMLファイルをGmailにインポートするための専門的な方法</h2>
<p>手動による変換には多くの制限があるため、お客様は、EMLを代わりにGmail電子メールクライアントに変換するための最良の代替オプションを選択することをお勧めします。ユーザーは、インテリジェントな<a href="https://www.mailsware.com/jp/eml-converter.html"><b>EMLコンバータソフトウェア</b></a>を使用して、PST、MSG、MBOX、EMLX、HTML、PDF、Gmail、Office 365、Yahooなどのさまざまな形式でEMLファイルを保存できます。メールボックスデータをEMLファイルに保存できる25を超える電子メールクライアントと互換性があります。以下に概説する方法に従って、EMLファイルをGmailに移行できます。</p>
<p>まず、WindowsマシンにEML to GmailConverterをダウンロードします。</p>
<p>このアプリを実行し、[フォルダーの選択]オプションをクリックして、EMLファイルをロードします。</p>
<p>このアプリは、左側のパネルにファイルをロードします。それをクリックして、完全なプレビューを確認してください。</p>
<p>次に、[変換]をクリックして、ファイル保存オプションとしてGmailを選択します。</p>
<p>Gmailアカウントのクレデンシャルを入力し、[Convery]ボタンをクリックして変換を開始します。</p>
<p>ソフトウェアはEMLファイルのGmailアカウントへの直接変換を開始します。このプロセスには少し時間がかかります。</p>
<h3>最終的な考え</h3>
<p>上記のブログ投稿では、EMLファイルをGmailアカウントにインポートするための最も推奨される方法について説明しました。データの損失など、移行への手動アプローチに関連する多くの危険があります。これらの制限をすべて克服するには、プロのEMLファイルコンバーターを使用することを強くお勧めします。これにより、迅速でトラブルのないソリューションが得られます。</p>
【git】一時退避する方法（メモ）

https://kaiblo.com/%e3%80%90git%e3%80%91%e4%b8%80%e6%99%82%e9%80%80%e9%81%bf%e3%81%99%e3%82%8b%e6%96%b9%e6%b3%95%ef%bc%88%e3%83%a1%e3%83%a2%ef%bc%89/

こちらに移動しました。
違うメソッドが呼ばれた時の対処法

#前提条件
Rails 6.1.3
#出てきたエラー
NoMethodError in PostsController#show

```posts_controller.rb
def show
    @post = Post.find_by(id: params[:id])
    @user = @post.user ←エラー
```
#不明点
showメソッドを呼んでないのに・・・NoMethodError in PostsController#showのエラーが出てしまう
#結論・解決法
routes.rbの順番を入れ替える
変更前

```routes.rb
Rails.application.routes.draw do
  get 'posts/:id' => 'posts#show'
  get 'posts/index' => 'posts#index'
end
```
変更後

```routes.rb
Rails.application.routes.draw do
  get 'posts/index' => 'posts#index'
  get 'posts/:id' => 'posts#show'
end
```
#補足
##1.ルーティングとは
ルーティングとは送信されたURLに対してどのコントローラーのどのアクションで
処理するかを決める対応表のことです。
例えば get"posts#index"ではpostsコントローラーのindexアクションを呼び出すということです
##2.ルーティングを実行する順番をする方法
$ rails routesを実行する
rails routesは各アクションのルーティングを確認する時、ルーティングを実行する順番を知りたい時に使います。
##3.順番を逆にするとNoMethodErrorが出る理由
上から順にコードを優先していくため:idが先になるようにコードを書くと:id以外の特定のURLを読み取る前に:idを実行してしまうからです。
#参考記事
[Rails routes.rbに書く順番](https://qiita.com/three_0_3/items/c39293237703ae81faec)
[Rails ルーティング 基礎 まとめ](https://qiita.com/akk11_k/items/a6a21beb2b736ebbc147)
[ルーティングの順番について (Progateにて)](https://qiita.com/gawach/items/4e7460d06f70e3013eea)　　
[rails routes（ルーティング）の順番の解説](https://qiita.com/harinezumi-html/items/46931ffc56c101fc6a4e)
【ionic】ion-cardが重なってしまう対処法 ion-virtual-scroll

## なに
ionicで開発をしているがion-cardコンポーネントの1つ１つがたまに重なってしまう現象があった。
この上の階層には``ion-virtual-scroll``というコンポーネントを使用しており、その子要素にion-cardが存在している。

## 対処法
この``ion-virtual-scroll``にitem1つ1つの高さを指定するfunctionを記述する。
そして、tsファイルの中にfunctionの記述をする。

### 編集前
```html
<ion-virtual-scroll [items]="stock_list" approxItemHeight="450px">
```

### 編集後
```html
// [itemHeight]="itemHeightFn"　を追記
<ion-virtual-scroll [items]="stock_list" approxItemHeight="450px" [itemHeight]="itemHeightFn">
```

```typescript
    /**
     * ion-cardのサイズ調整
     */
    itemHeightFn(item, index) {
        console.log('ゴリラがんばれ');
        if (window.innerWidth < 480) {
        //モバイルサイズの場合の記述
            return 280;
        }

        if (window.innerWidth <= 768 && window.innerWidth > 480) {
        //タブレットサイズの場合の記述
            return 450;
        }

        if (window.innerWidth > 768) {
        //PCサイズの場合の記述
            return 550;
        }
    }
```

条件のところで数字にしているところはマジックナンバーになってしまうため、あとは何かわかりやすい定数にしておく。
リンクをクリックするとjavascriptで指定の要素にスクロールする方法

## やりたいこと
* リンクをクリックすると、指定の要素にスクロールする
* javascriptで実現する

## イメージ
「About」というリンクをクリックすると
![スクリーンショット 2022-02-08 18.00.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/831027/4d252dcc-9681-ee49-ea2e-e45f8ba51f4e.png)

「About」のh2にスクロールする
![スクリーンショット 2022-02-08 18.01.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/831027/4f26e7de-b50d-eb63-de85-8dfb7b565cd3.png)

## ソースコード
### HTML
```
<a href="javascript:void(0);" onclick="scrollwindow('about');">About</a>
・・・
<h2 id="about">About</h2>
```
#### ポイント
* aタグに `href="javascript:void(0);"` をつけないと、ページの一番上に戻ってしまうので注意
* aタグの `scrollwindow` に渡す引数は、スクロール先の要素のidと同じにする

※関数 `scrollwindow` は仮名なので、何でも可

### javascript
```
function scrollwindow(elem) {
  var left = document.getElementById(elem).getBoundingClientRect().left;
  var top = document.getElementById(elem).getBoundingClientRect().top;
  window.scrollTo({
    left: left,
    top: top,
    behavior: "smooth",
  });
}
```
#### ポイント
* 引数 `elem` が、スクロール先の要素のidになる
* `window.scrollTo` で `behavior: "smooth"` を付与することでスクロールする(無いと瞬時に移動する)
[Python]画像の余白を白埋めして正方形にする方法

#はじめに
画像を正方形にリサイズしたいとき，画像のアスペクト比を維持しようとするとどうしても上下左右のいずれかに足りない画素が生まれてしまいます．
そんなときにその余白を適当な画素で埋めて正方形の画像をつくるプログラムをOpenCVとPillowで記述しました．
余白を作る際には対象の画像が上下左右いずれにおいても中心になるようにしています．
一応リサイズするプログラムも載せていますが白埋めだけなら要らないです．

※正方形以外の画像の余白埋めには対応していません．

#実際の画像変換例
![変換例.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327561/a596ac9e-7098-d825-fb3e-8d320a2c8b4d.jpeg)


#コード

##リサイズする
```Python
def resize (image, size):
    h, w = image.shape[:2]
    aspect = w / h
    nh = nw = size
    if 1 >= aspect:
        nw = round(nh * aspect)
    else:
        nh = round(nw / aspect)

    resized = cv2.resize(image, dsize=(nw, nh))

    return resized

```

##白埋めする
```Python
def shiroume (image, size):
    resized = resize(image, size)

    h, w = resized.shape[:2]
    x = y = 0
    if h < w:
        y = (size - h) // 2
    else:
        x = (size - w) // 2

    resized = Image.fromarray(resized) #一旦PIL形式に変換
    canvas = Image.new(resized.mode, (size, size), (255, 255, 255)) # 黒埋めなら(0,0,0)にする
    canvas.paste(resized, (x, y))

    dst = np.array(canvas) #numpy(OpenCV)形式に戻す
    
    return dst

```

##main()

```Python
import numpy as np
import cv2
from PIL import Image

image = cv2.imread('./hoge.jpg')
ume_image = shiroume(image, 600) #リサイズしたいサイズを指定
cv2.imwrite('./hogehoge.jpg', ume_image)
```

#参考サイト
https://pystyle.info/opencv-resize/#outline__3_5

https://note.nkmk.me/python-pillow-add-margin-expand-canvas/
PHP独学ノート　その1

PHPは<?php~?>（スクリプトブロック）の~の部分に処理を記述する。
なお、スクリプトブロックが.phpファイルの末尾で終わる場合はスクリプトの終了を表す ?> は省略できる。
むしろ省略しないとレイアウトに微妙にズレるので省略した方が良い。



出力方法はecho か　print。

```
<?php echo ‘Hello php’; ?>
<?php print “Hello php”; ?>

```

文字列を指定する場合には必ず前後を　‘ シングルクォートか “ ダブルクォートでくくる必要がある。



PHPはHTML埋め込み型言語である。

なのでHTML内に記述することができる。

```
<h3><?php echo “Hello php”; ?></h3>

```

省略構文
出力するべき値が増えてくると　php や　print といった記述ですら間違えやすさに直結する。
なので単純な値を出力する場合に<?php~?>の代わりに、
<?=~?>がある。

```
<?= ‘Hello php’; ?>
<?= “Hello php”; ?>

```

PHPでは、文の区切りに　; セミコロンを使う必要がある。
PHPでは改行しても命令文が終了したことにはならないので注意。
次のような記述はエラーとなる。

```
print ‘こんにちは、世界<be/>’
print ‘こんにちは、皆さん’

```

上記は　; がないのでエラーとなる。

命令文と改行
文の終わりは ; で表すので一つの文が長い場合には意味ある単語（キーワード）の区切りで有れば途中で空白や改行を加えても良い。

以下のルールによる改行が望ましい。
①文が80桁を超えた場合に改行。
②改行位置は , カンマや　演算子　などの直後。
③文の途中で改行した場合には、次の行にインデント（字下げ）を加える。

改行はあくまで空白としての意味しかないので文そのものは ; で区切れていれば良い。


```
print ‘こんにちは、世界<be/>’; print ‘こんにちは、皆さん’;

```

上記は間違いではないが良いコードではない。
どんなに短い文であっても、複数の文を1行にまとめない。
Angular + Amplify 〜トラブルシュート編

# 目次
1. [Angular + Amplify 〜準備編](https://qiita.com/nishitaku/items/c017d05615cecce25ebb)
1. [Angular + Amplify 〜Analytics編](https://qiita.com/nishitaku/items/9b9e367a8a9cc783b85b)
1. Angular + Amplify 〜トラブルシュート編

# トラブルシュート
### `aws-export.js`のimport文で`implicitly has an 'any' type.`
`src/@types/aws/aws-exports.d.ts`を作成。

```typescript:aws-exports.d.ts
declare const awsmobile: {};
export default awsmobile;
```

`tsconfig.json`を修正して`.js`ファイルを有効化。

```json:tsconfig.json
{
  "compilerOptions": {
    "allowJs": true
  }
}
```

### "export 'GraphQLError' was not found in 'graphql'

Angular v12からwebpack 5になったことで発生するらしい。[参考](https://github.com/aws-amplify/amplify-js/issues/4387)

`@angular-builders/custom-webpack`を追加。

```shell
npm install -D @angular-builders/custom-webpack
```

`custom-webpack.config.js`を追加。

```javascript:custom-webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.m?js/,
        resolve: {
          fullySpecified: false,
          fallback: {
            crypto: false,
          },
        },
      },
    ],
  },
};
```

`angular.json`を修正。

```json:angulsr.json
"architect": {
  "build": {
    // 変更
    "builder": "@angular-builders/custom-webpack:browser",
    // 追加
    "options": {
      "customWebpackConfig": {
        "path": "./custom-webpack.config.js",
        "mergeRules": {
          "module": {
            "rules": "prepend"
          }
        },
        "replaceDuplicatePlugins": true
      },
      "allowedCommonJsDependencies": [
        "uuid",
        "ulid",
        "url",
        "lodash/get",
        "lodash/isEmpty",
        "lodash/isEqual",
        "@aws-amplify/core",
        "buffer",
        "@aws-crypto/sha256-js",
        "crypto-js/hmac-sha256",
        "crypto-js/lib-typedarrays",
        "crypto-js/core",
        "zen-observable",
        "js-cookie",
        "isomorphic-unfetch",
        "@aws-crypto/crc32",
        "fast-xml-parser",
        "@aws-crypto/sha256-browser",
        "axios"
      ],
   ...
   },
   ...
   "serve": {
      // 変更
      "builder": "@angular-builders/custom-webpack:dev-server",
   ...
  }
```

`pacakge.json`に設定を追加。

```json:pacakge.json
{
  "browser": {
    "crypto": false
  }
}
```

### Uncaught ReferenceError: global is not defined

`src/polyfills.ts`に以下のコードを追加。

```typescript:polyfills.ts
(window as any).global = window;
(window as any).process = {
  env: { DEBUG: undefined },
};
global.Buffer = global.Buffer || require('buffer').Buffer;
```


# 参考
- [Angular6で”global is not defined”が出た時の回避策](https://dev.classmethod.jp/articles/angular6-referenceerror/)
Angular + Amplify 〜Analytics編

# 目次
1. [Angular + Amplify 〜準備編](https://qiita.com/nishitaku/items/c017d05615cecce25ebb)
1. Angular + Amplify 〜Analytics編
1. [Angular + Amplify 〜トラブルシュート編](https://qiita.com/nishitaku/items/6a58da3f69eae3cf52fb)

# 前提条件
[Angular v12 + Amplify 〜準備編]()が完了していること

# Amplify Analyticsでできること
[公式ドキュメント](https://docs.amplify.aws/lib/analytics/getting-started/q/platform/js/)
- カスタムイベントの記録（ Amazon Pinpoint ）
- セッション追跡、ページビューの追跡、ページイベントの追跡（ Amazon Pinpoint ）
- 分析データのストリーミング（ Amazon Kinesis Data Streams ）
- 分析データの保存（ Amazon Kinesis Firehose ）
- Amazon Personalize へのイベントデータの送信

# 今回やること
カスタムイベントの記録（ Amazon Pinpoint ）

# セットアップ
Analyticsカテゴリを追加する。

```shell
% amplify add analytics
Initializing new Amplify CLI version...
Done initializing new version.
Scanning for plugins...
Plugin scan successful
? Select an Analytics provider Amazon Pinpoint
? Provide your pinpoint resource name: angularamplify
Adding analytics would add the Auth category to the project if not already added.
? Apps need authorization to send analytics events. Do you wan
t to allow guests and unauthenticated users to send analytics 
events? (we recommend you allow this when getting started) Yes


Successfully added auth resource locally.
Successfully added resource angularamplify locally

Some next steps:
"amplify push" builds all of your local backend resources and provisions them in the cloud
"amplify publish" builds all your local backend and front-end resources (if you have hosting category added) and provisions them in the cloud
```

Authカテゴリが未追加だった場合は、同時に追加されます。
また、デフォルトだとPinpointのリージョンが`us-west-2`になっています。([amplify-cliのバグ?](https://github.com/aws-amplify/amplify-cli/issues/1965))
変更したい場合は、`amplify/backend/analytics/resourcename/pinpoint-cloudformation-template.json`の`RegionMapping`を修正してください。

`amplify push`してバックエンドにデプロイ。

```shell
% amplify push
✔ Successfully pulled backend environment dev from the cloud.

Current Environment: dev

| Category  | Resource name   | Operation | Provider plugin   |
| --------- | --------------- | --------- | ----------------- |
| Auth      | cognitoda374191 | Create    | awscloudformation |
| Analytics | angularamplify  | Create    | awscloudformation |
? Are you sure you want to continue? Yes
⠏ Updating resources in the cloud. This may take a few minutes...

UPDATE_IN_PROGRESS amplify-angularamplify-dev-232821 AWS::CloudFormation::Stack Fri May 28 2021 11:09:11 GMT+0900 (日本標準⠋ Updating resources in the cloud. This may take a few minutes...

(省略)

UPDATE_COMPLETE                     amplify-angularamplify-dev-232821 AWS::CloudFormation::Stack Fri May 28 2021 11:10:39 GM✔ All resources are updated in the cloud
Pinpoint URL to track events https://ap-northeast-1.console.aws.amazon.com/pinpoint/home/?region=ap-northeast-1#/apps/838a715982f04efd9a64cd1201d13ad2/analytics/overview
```

# カスタムイベントの記録
これだけ。

```typescript
Analytics.record({ name: 'albumVisit' });
```

# 参考
- [AWS Amplify の Analytics カテゴリまとめ](https://qiita.com/akitsukada/items/6dff5a90d81765f83ab6)
Angular + Amplify 〜準備編

# 目次
1. Angular + Amplify 〜準備編
1. [Angular + Amplify 〜Analytics編](https://qiita.com/nishitaku/items/9b9e367a8a9cc783b85b)
1. [Angular + Amplify 〜トラブルシュート編](https://qiita.com/nishitaku/items/6a58da3f69eae3cf52fb)

# 前提条件
- AWSアカウントを持っている
- npmコマンドが使える

# 今回やること
- フロントエンド(Angular)の構築
- Amplifyの初期設定

# Angularの構築

### プロジェクトの初期化
Angular CLIを使います。

```shell
npm i @angular/cli
```
今回はv12.0.0でやります。

```shell
ng --version
Angular CLI: 12.0.2
```

`ng new`でプロジェクトを作成します。
ルーティング、CSSはお好みで。

```shell
ng new angular-amplify
? Would you like to add Angular routing? Yes
? Which stylesheet format would you like to use? SCSS   [ https://sass-lang.com/documentation/syntax#scss
```
:::note info
以降は必要な場合のみ
:::

### ESLint

Angularはv12からTSLintがドロップされて、Linterが入っていないので、ESLintを入れます。
Schematicsが用意されているので、それを使います。

```shell
ng add @angular-eslint/schematics
```

### Prettier

フォーマッタはPrettierを使います。
ESLintとの競合を解消するために、`eslint-config-prettier`も入れます。
最近は`eslint-plugin-prettier`は非推奨みたいですね。([参考](https://github.com/prettier/prettier/blob/main/docs/integrating-with-linters.md))

```shell
npm install -D prettier eslint-config-prettier
```

`.eslintrc.json`を編集します。

```json:.eslintrc.json
{
    "extends": [
        // extendsの一番下に下記を追加
        "prettier"
    ]
}
```
`.prettierrc`も追加。設定はお好みで。

```json:.prettierrc
{
  "tabWidth": 2,
  "singleQuote": true,
  "trailingComma": "es5",
  "semi": true
}
```

フォーマッタを実行するコマンドを追加しておきます。

```json:package.json
{
  "scripts": {
    "format:check": "prettier --check 'src/**/*.ts' 'src/**/*.html'",
    "format": "prettier --write 'src/**/*.ts' 'src/**/*.html'"
  }
}
```

### Angular Material

```shell
ng add @angular/material
```

# Amplifyの初期設定

### Amplify CLIのインストール

```shell
npm install -g @aws-amplify/cli
```

### 初期設定

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

```shell
amplify configure
```
AWSアカウントの認証後、Amplify用IAMユーザーを作成し、認証情報をローカルに保存します。
`~/.aws/credential`にユーザー情報が保存されていればOK。

```
[profile name]
aws_access_key_id=******************
aws_secret_access_key=******************
```

次に、以下のコマンドを実行します。

```shell
amplify init
```

実行するとプロジェクト名やエディタなどを聞かれるので、対象のものを選択します。
プロファイルは先程作成したIAMユーザーのプロファイルを指定します。

成功すると、プロジェクトルートに`amplify`ディレクトリと、`src/aws-export.js`ファイルが生成されます。

```javascript:aws-export.js
// WARNING: DO NOT EDIT. This file is automatically generated by AWS Amplify. It will be overwritten.

const awsmobile = {
    "aws_project_region": "ap-northeast-1"
};


export default awsmobile;
```

また、この時点では何もありませんが、`amplify status`でAmplifyの状態を見ることができます。

# AngularからAmplifyを使う

### Amplifyライブラリを追加

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

```shell
npm install aws-amplify
```

### Angularの設定

`main.ts`に以下のコードを追加します。

```typescript:main.ts
import Amplify from 'aws-amplify';
import awsconfig from './aws-exports';

Amplify.configure(awsconfig);
```

# 参考
- [Angular v12 に ESLint を導入する](https://zenn.dev/koz/articles/e4872b6057dae2)
- [[Angular] ESLint環境にPrettierを導入する](https://qiita.com/reriiasu/items/f3104862808c0b12ba7e)
- [Amplify CLI をインストールしてユーザーを設定する手順](https://dev.classmethod.jp/articles/aws-cli-install/)
GPIOの探索スクリプト

ルーターなどの未知のGPIOを探索するためのmruby-bsdgpioを使ったGPIOのチェックプログラムを作ってみました。

```ruby:gpio.rb
#!/usr/local/bin/mruby
# ./gpio.rb <device number> <operation> <ignore list>

t = BsdGpio.new(ARGV[0].to_i)

opt = ARGV[1]

if ARGV.size == 3 then
  ignore = ARGV[2].split(',')
else
  ignore = []
end

n = 0
while n <= t.maxpin
  if !ignore.include?(n.to_s) then
    if opt == "in" then
      t.setflags(n, BsdGpio::INPUT)
    else
      t.setflags(n, BsdGpio::OUTPUT)
    end
    if opt == "1" || opt == "check" then
      t.set(n, 1)
      o = t.get(n)
    end
    if opt == "0" || opt == "check" then
      t.set(n, 0)
      z = t.get(n)
    end
    if opt == "check" then
      if z == 0 && o == 1
        p n.to_s + " OK" 
      else
        p n.to_s + " NG" 
      end
    end
  end
  n = n + 1
end
```

第一引数がデバイス番号で第二引数が0,1,check,inのどれかで、すべてを0か1にするか、checkはOUTした0,1が読めるかのチェックになり、inはすべてINPUTにします。

mediatekのSOCは[pinコントロール](https://qiita.com/yamori813/items/4fcb3a784f13e328917b)でGPIO以外の設定になっている場合は、checkでNGになります。GPIOでもスイッチなどの入力系はエラーになる事があります。

第三引数はある場合は、カンマ区切りの無視リストです。これはGPIOを設定してしまうとリセットするようなポートがある場合に使います。

```
# ./gpio.rb 1 check 0,3
```

のように使います。

このスクリプトであたりをつけてgpioctlコマンドで個別の確認を行います。

linux方面のdtsファイルがあればそれを参考にすると良いです。

これでやっとUSBのPowerのコントロールが見つかりました。
Webの勉強はじめてみた その29 〜Webフレームワーク〜

N予備校「プログラミング入門Webアプリ」を受講しています。
今回から第4章になります。

<h2>Expressの導入</h2>
Webフレームワークとして、`Express`を使います。
雛形を作るための`express-generator`をインストール

```
yarn global add express-generator@4.16.0
```

テンプレートエンジンを`pug`に設定して、カレントディレクトリに雛形を作成する

```
express --view=pug .
```

`package.json`の中を見ると、`yarn start`で起動できることがわかる。

```json:package.json
"scripts": {
    "start": "node ./bin/www"
  }
```

Portの設定

```javascript:www
/**
 * Get port from environment and store in Express.
 */

var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
```

デフォルトでは3000番。
dockerと同じ設定にするとスムーズ。

```
PORT=8000 yarn start
```

コンソールにログを出す時は、環境変数の`DEBUG`を利用する。

```
DEBUG=express-test:* PORT=8000 yarn start
```

<h2>helmetモジュール</h2>
:::note
Express の機能を拡張し HTTP において脆弱性となるヘッダなどを取り除いて安全に使える
:::

デベロッパーツールで簡単に確認できてしまう情報があるため。

```
yarn add helmet@4.6.0
```

`helmet`モジュールを`use`関数で登録する。

```javascript:app.js
var express = require('express');
var helmet = require('helmet');
var app = express();
app.use(helmet());
```

<h2>まとめ</h2>
:::note
Express というフレームワークは該当するパスや条件に関して、Router オブジェクトのような処理を実行するオブジェクトを複数登録し逐次処理していく仕組みで作られている。
この逐次処理を行っていく関数のことをハンドラという。
:::

フレームワークと言われると、`.NET Framework`がパッと思いつく。jQueryなんかもそうなのかな。
何にしても細かいことを気にしないで済むというのはとてもいい。
ただある程度は理解して使っていきたい。