OmniAICreator/Qiita-1.07M huggingface dataset:
Check that your cafile/capath settings〜なるエラーに騙された話

# 問題

古いシステムをPHP 7.4に上げようとしていました。アクセスするのにクライアント証明書が必要な社内向けAPIがありまして、このアクセスがうまくいきません。

エラーメッセージはこんな感じ:

```text
warning: file_get_contents(): Unable to set local cert chain file `xxx.pem`:
 Check that your cafile/capath settings include details of your certificate
 and its issuer in foo.php on line XX
```

# 調査

このエラーを見た私は、「cafile/capathの設定をチェックしろ? たしかに社内向けプライベート認証局とか使うので変な設定してるしなあ...」と思ってそのあたりをいくらチェックしてもおかしいところは見当たりません。

でもこれ古いシステムではちゃんと使えてるやつだし、と思って[SSLコンテキストオプション](https://www.php.net/manual/ja/context.ssl.php)のマニュアルを眺めていたら、7.2から使える`security_level`という設定があるのに気がつきました。

とりあえず下げてみるかとおもって0にするとこれが当たりでアクセスできるようになり、さらに試すと1まではアクセス可、2で上記のエラーになることが判明しました。

`security_level`の値については[SSL_CTX_set_security_level](https://www.openssl.org/docs/man1.1.0/man3/SSL_CTX_get_security_level.html)のマニュアルを見ろと書いてあるのでそちらを見ますと、

> Level 1
The security level corresponds to a minimum of 80 bits of security. Any parameters offering below 80 bits of security are excluded. As a result RSA, DSA and DH keys shorter than 1024 bits and ECC keys shorter than 160 bits are prohibited. All export ciphersuites are prohibited since they all offer less than 80 bits of security. SSL version 2 is prohibited. Any ciphersuite using MD5 for the MAC is also prohibited.

> Level 2
Security level set to 112 bits of security. As a result RSA, DSA and DH keys shorter than 2048 bits and ECC keys shorter than 224 bits are prohibited. In addition to the level 1 exclusions any ciphersuite using RC4 is also prohibited. SSL version 3 is also not allowed. Compression is disabled.

とあり、Level 1だとRSA 1024ビット以上、Level 2だとRSA 2048ビット以上とありますが、使ってる証明書は2048ビットでこれは外れ。しかしさらに読み進めるとNOTESのところに

>WARNING at this time setting the security level higher than 1 for general internet use is likely to cause considerable interoperability issues and is not recommended. This is because the SHA1 algorithm is very widely used in certificates and will be rejected at levels higher than 1 because it only offers 80 bits of security.

とあり、署名にSHA1使ってるとlevel 1までだよと書いてありました。確認すると例のAPIの管理元からもらったクライアント証明書はSHA1で署名されていてこれが問題だとわかりました。

# エラーメッセージおかしくない?

一応問題は解決したのですが、この問題にcafile/capathは結局全然関係ないのでなんか納得いきません。

例のエラーメッセージでphpのソースをgrepすると以下のようになっていました。(ext/openssl/xp_ssl.c)

```c
			if (SSL_CTX_use_certificate_chain_file(ctx, resolved_path_buff) != 1) {
				php_error_docref(NULL, E_WARNING,
					"Unable to set local cert chain file `%s'; Check that your cafile/capath "
					"settings include details of your certificate and its issuer",
					certfile);
				return FAILURE;
			}
```

つまりこのエラーメッセージは単に`SSL_CTX_use_certificate_chain_file`に失敗したことを示しているだけでエラーの内容については何も見ていません。cafile/capathがどうのというのはいわば当てずっぽうです。

# `openssl_error_string`を使いましょう

実はopensslはエラーについての情報を内部で保持していて、エラーメッセージを取り出すAPIが用意されています。phpのopenssl拡張にも、[`openssl_error_string`](https://www.php.net/manual/ja/function.openssl-error-string.php)という関数が用意されています。

エラーになった`file_get_contents`のあとでこれを使ってエラーを出力してやると、

```text
error:140AB18E:SSL routines:SSL_CTX_use_certificate:ca md too weak
```

と出まして、これ読んでもさっぱり意味が分かりませんが、'ca md too weak'でググるとsecurity levelとSHA1署名が問題であることがわかりますから、cafileの確認などに時間を浪費せずに早く正解にたどり着けたのではないかと思います。
[Ruby]スキルチェックC練習問題　Fizz Buzz

https://paiza.jp/works/mondai/skillcheck_sample/fizz-buzz


Fizz Buzz (paizaランク C 相当)
C問題に挑戦してみました！
こちらはスキルチェックの見本問題なので、コードの公開等は自由だそうです。


私の解答コード↓

```
input_line = gets.to_i

for i in 1..input_line
　if i%15==0　　　　　　
 　puts"Fizz Buzz"
　elsif i%3==0
 　puts"Fizz"
　elsif i%5==0
 　puts"Buzz"
　else
 　puts i
　end
end
```


まず最初に標準入力で与えられた数字まで、順に数字を出力するように記述し、それからif文を入れていきました。
（プログラミングはまず小さいところから、、でしたっけ...?)


```
input_line = gets.to_i
与えられた文字まで、１ずつ出力する。

for i in 1..input_line
puts i
end

```

ちなみにpaizaの解答コードは、if文をこんな風に記述していました。

```
if (i % 15).zero?
```




今回のc問題は自力でできました。
【Flutter】Flutter webで画像をURLごと読み込むときに表示されない対処法

Flutter webで画像をURLごと読み込もうとしたときにxのような表示になってしましました。
その解消法を記述します。

![スクリーンショット 0003-06-24 10.17.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163786/a97223c3-6f6b-711e-a5bf-d37a8493fa79.png)


Flutter内で下記のようにURLごとimageファイルを読み込みます。

```dart
child: Image.asset('https://sample.com/images/sample.jpg'),
```

すると下記のようなエラーが表示されます。

```
Another exception was thrown: ImageCodecException: Failed to load network image.
```

原因はここに書いてありました。

https://flutter.dev/docs/development/platform-integration/web-images

デフォルトの`レンダラー`が`HTML`から`canvaskit`に切り替わったようです。

> The CanvasKit renderer implements Flutter’s image API fully. However, it requires access to image pixels to do so, and is therefore subject to the CORS policy.

## 解決方法
mobileで見るときはそのままでいけますがwebで見るときは`canvaskit`の代わりに`html`レンダラーを使用してくださいとのことのようです。

下記のコマンドで実行してみてください。

```
flutter run -d chrome --web-renderer html
```

これでｘだった画像がうまく表示されたと思います。
Flutter Webのときは注意してください。
【Google Cloud Day'21】「Google Cloud で実現する安心、安全なクラウド導入のためのポイント 5 選」を視聴して

https://cloudonair.withgoogle.com/events/google-cloud-day-digital-21/watch?talk=d1-pl-12
Google Cloud で実現する安心、安全なクラウド導入のためのポイント 5 選
"概要：クラウドにシステムを導入することに躊躇していませんか ? クラウドへのシステム導入で最も重要な課題となるのは自社のセキュリティ要件との適合です。セキュリティを担保しつつクラウドでの高速なシステム開発を実現するために必要なポイントについて、実際の経験を元に Google Cloud 公式のセキュリティ基盤のブループリント ガイドとエンタープライズ企業のベストプラクティスを 30 分に凝縮してお伝えします。
"

<table>
	<tr>
		<th>切り口</th>
		<th>内容</th>
	</tr>
	<tr>
		<th>一般的なセキュリティ要件</th>
		<td></td>
	</tr>
	<tr>
		<th>セキュリティ強化の５つのポイント</th>
		<td></td>
	</tr>
	<tr>
		<th>アカウント認証</th>
		<td></td>
	</tr>
	<tr>
		<th>ネットワークセキュリティ</th>
		<td></td>
	</tr>
	<tr>
		<th>データ管理</th>
		<td>IAMでAllusersにすると公開されてしまうので、共有VPCと組み合わせて特殊な設定をする。国内の法律を適用したいなら、国内のリージョンに保存しないといけない</td>
	</tr>
	<tr>
		<th>システムセキュリティ</th>
		<td>オンプレミスで実現するとなるとかなり手間がかかるが、GCPだと簡単に設定できる。</td>
	</tr>
	<tr>
		<th>セキュリティ統制</th>
		<td>組織ポリシーの機能がとても使える。間違って違うドメインのアカウントを許可しないようにできる。セキュリティ統制を機能面で徹底することが可能。</td>
	</tr>
</table>

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/5264def0-4550-1cb3-e141-b0b56d42f90a.png)
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/e0a6f053-1c56-9a89-0a18-140ec8df3470.png)
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/7fd24cd4-421f-06e5-e9de-b9bdc1b84bbf.png)
in句の検索を複数カラムで行う。

例として以下の様なエンティティを持つ、studentsテーブルがあるとする。

■studentsテーブル

school_year|class_name|attendance_number|name|
---|---|---|---|
|学年|クラス|出席番号|名前|


上記テーブルは、
school_year,class_name,attendance_numberによる複合主キーを持つ。

例えば、
1年,A組,1番
2年,A組,8番　の生徒を出力したい場合は以下のようにする。

```sql
select * from students 
         where (school_year,class_name,attendance_number) 
          in ((１年,A組,1番),
              (2年,A組,8番));
```

in句にサブクエリを使うこともできる。

```sql
select * from students 
         where (school_year,class_name,attendance_number) 
          in (select school_year,class_name,attendance_number from ......);
```
【Google Cloud Day'21】「BigQuery を活用したデータ分析プラットフォームの優位性と課題とは？」を視聴して

"概要：弊社では、2019 年にデータ分析プラットフォームをオンプレミスから Google Cloud に移行しました。全社のビジネスデータをBigQuery に収集する取り組みを現在も継続して行っています。
プロジェクト企画からシステム稼働後までの具体的なエピソードを交えつつ、取組みの中で学んだ BigQuery の優位性や課題について説明させていただきます"
https://cloudonair.withgoogle.com/events/google-cloud-day-digital-21/watch?talk=d1-da-01

<table>
	<tr>
		<th>質問</th>
		<th>回答</th>
	</tr>
	<tr>
		<th>こちら、一番ネックはどのようなものがありましたでしょうか？（技術的問題・金銭的問題・社内状況の調整など）</th>
		<td>技術的な問題が大きいです。BigQueryに対応するSASのアダプターを取り扱った事例が無かったので、リスクヘッジの検討に非常に時間がかかりました。</td>
	</tr>
	<tr>
		<th>現在のBigQueryで解決できなかったユースケースがあることでさらなる改善を求められていると想定しますが、どのようなケースでしょうか？</th>
		<td>あくまで、データをBigQueryに一元化し、パフォーマンス改善やデータ鮮度の向上が実現出来ただけです。例えばデータマートの更なる整備により、誰もがデータを分かりやすく扱えるようになるとか、AI等のソリューションを用いてビジネスにデータを活用していくとか、今後はデータ利活用に向けた取り組みが必要と考えています</td>
	</tr>
	<tr>
		<th>PoCが非常に大変な中、それでも諦めずにBigQueryへの移行を進めることができたのには何か理由があったのでしょうか。</th>
		<td>PoC自体が大変だったわけではないです。プロジェクト自体は様々な課題がありましたが、無事にスケジュール通り進捗し、プロジェクト課題を解消できたのは、同じ目的に向かってベンダーさん、ユーザ部門、ITで三位一体で進められたからだと思います。</td>
	</tr>
</table>


<table>
	<tr>
		<th>切り口</th>
		<th>内容</th>
	</tr>
	<tr>
		<th>従来の環境</th>
		<td></td>
	</tr>
	<tr>
		<th>課題</th>
		<td>オンプレミスは厳しい。</td>
	</tr>
	<tr>
		<th>課題を解決しようとしたが・・・</th>
		<td></td>
	</tr>
	<tr>
		<th>なぜBQか</th>
		<td>すでに上の分散したクラウド環境の中でBQも使っていた。そのなかでBQを使ったほうがいいという意見になった。</td>
	</tr>
	<tr>
		<th>BQにした結果</th>
		<td>プラットフォームの維持コストも下がった。ユーザーの不満もなくなった。</td>
	</tr>
</table>

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/3faba8a2-ce12-14fd-ba82-d1b30bd3f9f9.png)
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/26d0e4ab-4051-e4d6-06e1-93ce5cffbb92.png)
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/87e68ae0-070e-84c7-35a9-98b7b121c415.png)
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/28ebd5fb-2f3b-2e28-546c-02f5ab8ee7a2.png)
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/535a6823-6a66-5f33-e80c-6ca55d9786a9.png)
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/a192a7dc-b86a-b381-dfac-cb07a999ad8e.png)
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/1e5f0e8f-3660-c8c9-79d7-bd053f6712ca.png)
STM32F103C8と秋月シリアル7セグで3分タイマー SPI


x Mbed2のリビジョンは、172
x Mbedでのボード設定は、NUCLEO-F103RB
x 赤色７セグメントＬＥＤシリアルドライバモジュール　完成品
x OSL10564-74HC595-R M-12642
x プログラムは、STM32F767と同じ
x ハードは、BluePill F103C8

説明
文字を文字パターンに変換する
64は、@の開始位置です。
7セグメントの文字パターンに変換
変換範囲は、32文字で5ビット分

メイン関数
main()
いろいろ初期化
1から3までを1分毎に7セグに表示して
無限ループで停止する

D13-PA_5 -> A5
D12-PA_6 -> A6
D11-PA_7 -> A7
D10-PB_6 -> B6



```c++

#include "mbed.h"

//*          *****  *****  
//*         *       *    * 
//*         ******  *    *
//*         *       *    *
//*         *       *    *
//********   *****  *****

#define swclk1  PA_5    //A4
#define test01  PA_6
#define swdio1  PA_7    //A6
#define en1     PA_4    //A3

SPI spi( D11 , D12 , D13); // mosi, miso, sclk //767
DigitalOut en( D10 ); //767

//SPI spi( swdio1 , test01, swclk1); // mosi, miso, sclk //010
//DigitalOut en(en1); //010

char seg[32] = {
   0x00 , //0 @ -> ' '
   0x77 , //1 A  o
   0x7c , //2 B     　combined use "6"
   0x39 , //3 C
   0x5e , //4 D
   0x79 , //5 E  o
   0x71 , //6 F
   0x3d , //7 G
             
   0x76 , //8 H  o
   0x06 , //9 I    　combined use "1"
   0x1e , //10 J
   0x75 , //11 K 
   0x38 , //12 L  o
   0x15 , //13 M
   0x37 , //14 N  o
   0x3f , //15 O  o　combined use "0"
              
   0x73  , //16 P
   0x67  , //17 Q　combined use "9"
   0x50  , //18 R
   0x6d  , //19 S　combined use "5"
   0x78  , //20 T
   0x3e  , //21 U
   0x1c  , //22 V
   0x2a  , //23 W  o
   0x64  , //24 X
               
   0x6e  , //25 Y
   0x5b  , //26 Z　combined use "2"
   0x4f  , //27 [  --> "3"
   0x66  , //28 \  --> "4"
   0x27  , //29 ]  --> "7"
   0x7f  , //26 ^  --> "8"
   0x08    //31 _
};


#define s60()   for(ii=0;ii<60;ii++)wait_ms(1000);

int main() {

    spi.format(8,0);
    spi.frequency(1000000);

    en=0;

    int ii; //ループカウンター

    //0分
    spi.write(seg['O'-64]);en=1;en=0;
    s60();

    //1分
    spi.write(seg['I'-64]);en=1;en=0;
    s60();

    //2分
    spi.write(seg['Z'-64]);en=1;en=0;
    s60();

    //3分
    spi.write(seg['['-64]);en=1;en=0;

    while(1){} //無限ループ

}//main

//容量削減
//void error(const char* format, ...){}



```


![spi_7seg_103_2_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/7ed016e4-e264-a4f5-8ab0-277269757fe7.jpeg)
pyenv備忘録

pyenv備忘録


```
$ tree -L 1 $HOME/.pyenv
/home/ubuntu/.pyenv
├── Dockerfile
├── Makefile
├── README.md
├── bin
├── completions
├── libexec
├── man
├── plugins
├── pyenv.d
├── shims
├── src
├── terminal_output.png
├── test
├── version
└── versions
```

pyenv local hogeがそのディレクトリ下でしか動かないことを確認する

```
hoge@LAPTOP-hoge:~/abc$ pyenv versions
  system
  2.7.15
  3.6.9
* 3.8.10 (set by /home/hoge/.pyenv/version)
```

globalで3.8.10が使われる設定になっている。
今いるディレクトリ下で使うpythonを3.6.9にする

```
hoge@LAPTOP-hoge:~/abc$ pyenv local 3.6.9

hoge@LAPTOP-hoge:~/abc$ pyenv versions
  system
  2.7.15
* 3.6.9 (set by /home/hoge/abc/.python-version)
  3.8.10
```
3.6.9が使われる設定になっているが、一個上のディレクトリではどうだろうか？

```
hoge@LAPTOP-hoge:~/abc$ cd ../
hoge@LAPTOP-hoge:~$ pyenv versions
  system
  2.7.15
  3.6.9
* 3.8.10 (set by /home/hoge/.pyenv/version)
```

一個上のディレクトリではpyenv global 3.8.10なので3.8.10が使われるようになっている。


pyenv local バージョン情報
としたディレクトリには.python-versionが作成され、中にはlocalで指定した3.6.9という文字が書き込まれている。

```
hoge@LAPTOP-hoge:~/abc$ ls
.  ..  .python-version
hoge@LAPTOP-hoge:~/abc$ cat .python-version
3.6.9
```

調べてみると詳しめの解説があるサイトにたどり着いた。

> https://outputable.com/post/about-pyenv/#pyenv-global
バージョン情報はpyenv localコマンドを実行したディレクトリに「.python-version」ファイルとして記述され、管理されています。
※globalや上位階層の「.python-version」より、より深い階層の「.python-version」が優先されるようです。
(より具体的に言うと、下層 -> 上層順に探索され、「$HOME/.pyenv/version」ファイルの情報もない場合、システムのPython, pipが呼び出されるようです)


shims以下のコマンド実行(local指定している場合)の挙動
→shims以下の同名コマンドが、.python-versionファイルに記載されたpythonを~/.pyenv/versions/から探し出して実行する


まとめ

`.python-version`がなければ`.pyenv/version`
それもなければsystemにあるpythonを使用

ex.
local指定がある場合python,pipなどのコマンドが実行されると、shims以下の同名コマンドが実行され
`.python-version`に記載のpythonバージョンのコマンドが`.pyenv/versions/以下`から実行される
local指定がない場合`.pyenv/version`に記載のpythonバージョンがversions以下のファイルから実行されるはず。(globalバージョンの情報は
`.pyenv/version`に記載される)それもなければsystemにあるpythonを使用。
[JavaScript]paizaスキルチェックD 「足し算」/JavaScriptで数値化するには?

https://paiza.jp/works/mondai/skillcheck_sample/addition

足し算 (paizaランク D 相当)
今度は、javaScriptで挑戦しました。
Rubyが完璧とは程遠い中でJavaScriptを勉強し始めたため、若干混ざってしまいます...
こちらの問題はpaizaのスキルチェックDの見本問題集の問題ですので、コードの公開は自由だそうです。



問題を開いて言語を選択した段階で、下記の通りコードが与えられますので、
追記、修正していきます。

```
process.stdin.resume();
process.stdin.setEncoding('utf8');
// 自分の得意な言語で
// Let's チャレンジ！！
var lines = [];
var reader = require('readline').createInterface({
  input: process.stdin,
  output: process.stdout
});
reader.on('line', (line) => {
    lines.push(line);　　　　　　　　　　　　　　　　　　　　　　　　　　＃配列にプッシュしてるのはわかる。
    
});
reader.on('close', () => {
  console.log(lines[0]);　　　　　　　　　　　　　　　　　　　　＃ここは（lines[0]+lines[1])に修正かな？
});
```
今のコードだと、入力される２つの値を配列に入れてるのはわかるのですが、
1 1 と入力された値をそのまま配列に入れてるので、本当は[1,1]としたいところが[1 1]になっています。
（splitを使って、配列作ればいいのかな。。分からない）


↓
↓
私の解答コード

```
process.stdin.resume();
process.stdin.setEncoding('utf8');
// 自分の得意な言語で
// Let's チャレンジ！！
var lines = [];
var reader = require('readline').createInterface({
  input: process.stdin,
  output: process.stdout
});
reader.on('line', (line) => {
    lines=line.split(" ").map(Number);
    
    
});
reader.on('close', () => {
  console.log(lines[0]+lines[1]);
});
```

<h1>JavaScriptで数値化するには...?

受け取った値を整数にしないとと思って浮かんだのは.to_iなのですが、それはRubyでした...

JavaScriptの記述では、Numberを使って数値にするんですね...

以下のコードでは、mapで配列の要素を取り出し、
Numberで数値にしているということですね。


```
lines=line.split(" ").map(Number);
```



https://qiita.com/k-ta-yamada/items/872057e7b42345e9f294



https://www.sejuku.net/blog/21812



もう少しRubyが固まってきてからJavascriptを勉強したほうがよかったのかなと思いつつ、、
とにかくどっちも頑張ります！！


ちなみに、RubyのスキルチェックDはクリアできました。（見本問題よりはるかに簡単でした）
標準入力・標準出力/エラー出力


本ページでは標準入出力とエラー出力について書いていきます。
Linuxに関してですが、個人的な慣れと共にJavaでの説明も混じっています。

コンピュータも、
何かアクションが無いと何も始まらないのは同じのようで…
やることは決まっていても、材料が無ければ何も作れません:cooking:
　例：身長・体重からBMIを算出→データが無いと計算できない　など


>データストリーム：コンピュータの、入力→処理→出力　の一連の流れ

入力は標準入力の１つ、
出力は標準出力と標準エラー出力の２つ

###標準入力 stdin
指定をしていないときはキーボードからの入力。
ファイルを指定することもできる　

前述のBMI算出例だと、できれば大人数のデータから調べたいですよね。
→リダイレクトの項目もご覧ください。

###標準出力　stdout
「出力する」というコマンドの時やコマンド実行の過程で通常処理が問題ない場合に端末に出力。
指定をしていないときはコンソール画面


上記標準入力・出力はまとめて標準入出力(stdio)とも。

###標準エラー出力　stderr
コマンド実行時に通常処理が行われず、エラーになった場合の出力に使われます。
端末画面で標準出力と大差ないように出力されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1620534/915396a1-b582-43ab-616b-d621635d505b.png)
該当ファイル・ディレクトリが無い場合、
このような「そのようなファイルやディレクトリはありません」エラーが出ます。
ちなみに、コマンド：---の---の数字はアドレスを指していてエラーになっているようでした。

####所感
「標準」というのは最低限、備え付けの、のような印象を持ちました。standard in/out~


###Javaのプログラミング的にも
プログラム実行時に指定するものではなく、プログラムを実行して入力の待ちになった時の方です。
Scannerクラス、InputStreamクラス、一番身近かもしれないSystemクラスのSystem.out,System.inが標準入力に当たるようです。

実行して入力が待ちになった状態からデータセットを逐一入力すると、データセットが多い場合には面倒、ミスも多くなります。
ファイルにデータセットを記述したものを入力元として読み込みたいときにこのリダイレクトを使用します。

##リダイレクト
以下Linuxでのリダイレクトです。

###標準入力をファイルで行う
```
コマンド < データファイル名
```
　入力したいデータファイルを用いる場合は“<”を使います。

###標準出力をファイルに行う
```
コマンド > 出力したいファイル名
```
　実行結果をファイル形式に出力したい場合には“>”を使います。

>出力したいファイル名がすでに存在している場合は、上書きされてしまうので
">"の代わりに">>"を使うと、追記されます。

シェルの種類によっては、>ではなく">&",割り当て番号を使うものもあります。

どちらも、コマンドに入る・出るイメージそのままで知っていれば利用しやすいですよね。

###割り当て番号
以下の番号でOSが入出力を認識できます。
標準入力　　　：0
標準出力　　　：1
標準エラー出力：2

これを用いると、実行結果とエラー出力を分けることができます。

```
コマンド 1> 実行結果ファイル名 2>エラー用ファイル名
```
両方使用するとこのような記述になるようです。
Action Textとransackの相性が悪くて困った

# はじめに
ポートフォリオにAction Textを導入してみたものの検索機能のgemであるransackとの相性が悪くて一度Action Textのを使うのを諦めたが悔しいから再度導入に挑戦したときの話です。

# Action Textとは？
そもそもAction TextとはRails6から導入された新機能で文字の色や大きさまた画像を埋め込める便利なエディタが簡単に作れるようになるやつです。
導入方法もすごく簡単なので気になる人はぜひ導入してみてください！

https://railsguides.jp/action_text_overview.html

# 現状把握
では本題です！
現状検索部分はnameとcontentカラムをransackで用意されているあいまい検索できるメソッド`cont`を使っています。
そしてAction Textを導入した際に出たエラーは以下です。

```ruby:ターミナル
NoMethodError - undefined method `name_or_content_cont'
```

でましたNoMethodErrorよく出るやつですね。
ちなみにnameだけなら検索できたのでこれはcontent部分が問題なのは明らかですね。

これなんで起きてるかDBを確認するとAction Textはcontentカラムを保存させるための本来のmodelテーブル（今回はPost modelとする）ではなく以下のようなAction Textが用意したテーブルに保存することになっているからなんですよね。
つまりPostテーブルにはcontentなんてものは存在しないのにransackでcontent検索してるからそんなもんないぞ！！ってことでエラーがで出たたわけなんですね。

```ruby:ターミナル
class CreateActionTextTables < ActiveRecord::Migration[6.0]
  def change
    create_table :action_text_rich_texts do |t|
      t.string     :name, null: false
      t.text       :body, size: :long
      t.references :record, null: false, polymorphic: true, index: false

      t.timestamps

      t.index [ :record_type, :record_id, :name ], name: "index_action_text_rich_texts_uniqueness", unique: true
    end
  end
end

```

# どうするか？
ransackの公式を見てもそれらしいのは見当たららなかったのでもうransackを使うのを諦めて検索機能を自作することにします！

# 実装
検索機能を自作するにあたってAction TextのテーブルをPostテーブルに内部結合することで実装できそうです。
実装したコードはこんな感じ

```ruby:post.rb
 scope :search, -> (search_param = nil) {
    return if search_param.blank?
    joins("INNER JOIN action_text_rich_texts ON action_text_rich_texts.record_id = posts.id AND action_text_rich_texts.record_type = 'Post'")
    .where("action_text_rich_texts.body LIKE ? OR posts.title LIKE ? ", "%#{search_param}%", "%#{search_param}%")
  }
```

## 解説

```ruby
 (search_param = nil)
return if search_param.blank?
```
この部分はblankだったら早期リターンつまり検索Formが空欄だった場合に対応しています。

```ruby
 joins("INNER JOIN action_text_rich_texts ON action_text_rich_texts.record_id = posts.id AND action_text_rich_texts.record_type = 'Post'")
```
内部結合部分
やっていることはAction Textテーブルのidとpostテーブルのidが同じかどうか、
Action TextテーブルがPostテーブルと紐付いているかどうかをjoinsで結合しています。

```ruby
.where("action_text_rich_texts.body LIKE ? OR posts.name LIKE ? ", "%#{search_param}%", "%#{search_param}%")
```
最後に検索条件部分
Action Textのbody（保存されている部分ですね）とpostテーブルのnameカラムをLIKEで検索しています。
また`%#{search_param}%`部分は検索formの値が渡ってくるんですが%で囲うことであいまい検索ができるようになっています。

これで完成！

# 最後に
一度導入を諦めましたが再度挑戦し無事実装できて本当に良かったです。
また検索機能を自作するときに色々調べたことでSQLの復習にもなったので何事もやってみるもんだなーって思いました！
STM32F303K8と秋月シリアル7セグで3分タイマー SPI


x Mbed2のリビジョンは、172
x Mbedでのボード設定は、NUCLEO-F303K8
x 赤色７セグメントＬＥＤシリアルドライバモジュール　完成品
x OSL10564-74HC595-R M-12642
x プログラムは、STM32F767と同じ

説明
文字を文字パターンに変換する
64は、@の開始位置です。
7セグメントの文字パターンに変換
変換範囲は、32文字で5ビット分

メイン関数
main()
いろいろ初期化
1から3までを1分毎に7セグに表示して
無限ループで停止する


```c++

#include "mbed.h"

//*          *****  *****  
//*         *       *    * 
//*         ******  *    *
//*         *       *    *
//*         *       *    *
//********   *****  *****

#define swclk1  PA_5    //A4
#define test01  PA_6
#define swdio1  PA_7    //A6
#define en1     PA_4    //A3

SPI spi( D11 , D12 , D13); // mosi, miso, sclk //767
DigitalOut en( D10 ); //767

//SPI spi( swdio1 , test01, swclk1); // mosi, miso, sclk //010
//DigitalOut en(en1); //010

char seg[32] = {
   0x00 , //0 @ -> ' '
   0x77 , //1 A  o
   0x7c , //2 B     　combined use "6"
   0x39 , //3 C
   0x5e , //4 D
   0x79 , //5 E  o
   0x71 , //6 F
   0x3d , //7 G
             
   0x76 , //8 H  o
   0x06 , //9 I    　combined use "1"
   0x1e , //10 J
   0x75 , //11 K 
   0x38 , //12 L  o
   0x15 , //13 M
   0x37 , //14 N  o
   0x3f , //15 O  o　combined use "0"
              
   0x73  , //16 P
   0x67  , //17 Q　combined use "9"
   0x50  , //18 R
   0x6d  , //19 S　combined use "5"
   0x78  , //20 T
   0x3e  , //21 U
   0x1c  , //22 V
   0x2a  , //23 W  o
   0x64  , //24 X
               
   0x6e  , //25 Y
   0x5b  , //26 Z　combined use "2"
   0x4f  , //27 [  --> "3"
   0x66  , //28 \  --> "4"
   0x27  , //29 ]  --> "7"
   0x7f  , //26 ^  --> "8"
   0x08    //31 _
};


#define s60()   for(ii=0;ii<60;ii++)wait_ms(1000);

int main() {

    spi.format(8,0);
    spi.frequency(1000000);

    en=0;

    int ii; //ループカウンター

    //0分
    spi.write(seg['O'-64]);en=1;en=0;
    s60();

    //1分
    spi.write(seg['I'-64]);en=1;en=0;
    s60();

    //2分
    spi.write(seg['Z'-64]);en=1;en=0;
    s60();

    //3分
    spi.write(seg['['-64]);en=1;en=0;

    while(1){} //無限ループ

}//main

//容量削減
//void error(const char* format, ...){}



```
Rails　個人的に覚えておきたいコマンド【初心者】

##操作取り消し系
<h3>コントローラ作成~取り消し</h3>
コントローラ作成　※例
```rails generate controller StaticPages home help```
取り消し　※上記で作成された関連ファイルもすべて削除される。
```$ rails destroy  controller StaticPages home help```

<h3>モデル作成~取り消し</h3>
モデル作成※例
``` $ rails generate model User name:string email:string```
取り消し※カラム名の指定は不要
``` rails destroy model User```

<h3>migrate~取り消し</h3>
migrate実行
```$ rails db:migrate```
１つ前に戻す
```$ rails db:rollback```
最初の状態に戻す
```$ rails db:migrate VERSION=0```
iPhone SafariのWebインスペクタが見られない！【Mac Safari14.1.1 / iOS14.6】

通常、MacにiPhoneをUSB接続することで、iPhoneで閲覧中のSafariのWebインスペクタをMacから確認、操作することができるようになります。
普段、自分のアプリを開発する際にはこの機能を活用していました。

ところが、先日MacOSをBigSur11.3から11.4へアップデートしたところ、このWebインスペクタに異常が！！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1102360/d26fd502-b0f6-4dac-6557-879a86335be9.png)

Webインスペクタは表示されるのですが、開くタブは３種類しかないし、開いているタブも全然機能していません。
（画像のようにconsole.logしても、なんの反応もありません）

色々調べても日本語のサイトでは不具合情報は見当たらず。
仕方なしに英語で検索してみると、ありました。

[Safari Web Inspector tabs are missing](https://developer.apple.com/forums/thread/680886)

どうやら、BigSur11.4で一緒にアップデートされた、MacのSafari14.1.1のバグのようです。

解決するには、以下のどちらかしかないようです。
- 次回アップデートを待つ
- Safari Technology Preview 125以降をダウンロードする[developer.apple.com/safari/download](https://developer.apple.com/safari/download/)

iOSのアップデートは、苦労が絶えませんね・・・
[メモ] Windows 10 に ssh ログイン



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75594/fb2a2662-73ba-ac54-0d3f-9b67a5490c8e.png) <br>VSCode のRemote SSHで、VMのWindows10にアクセス。

# 概要
Windows 10 に OpenSSHサーバをインストール、PubKeyでログインできるようにする。(VSCodeで、Remote SSH から使える)


# 手順
## OpenSSHサーバのインストール

https://docs.microsoft.com/ja-jp/windows-server/administration/openssh/openssh_install_firstuse

- PowerShellを管理者で開く

	```powershell:管理者
	# Install the OpenSSH Server
	Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
	#
	# Start the sshd service
	Start-Service sshd
	# サービス自動起動
	# OPTIONAL but recommended:
	Set-Service -Name sshd -StartupType 'Automatic'
	#
	#
	# ファイアウォールの設定確認と設定
	# Confirm the firewall rule is configured. It should be created automatically by setup.
	Get-NetFirewallRule -Name *ssh*
	#
	# There should be a firewall rule named "OpenSSH-Server-In-TCP", which should be enabled
	# If the firewall does not exist, create one
	New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
	```

## 設定変更
https://docs.microsoft.com/en-us/windows-server/administration/openssh/openssh_keymanagement

1. ssh関連の設定ファイルは、`C:\ProgramData\ssh\`の中。
sshdの設定ファイル`sshd_config`  を管理者でテキストエディタを開いて、以下のように編集

	```txt:sshd_config
	# pubkeyでログイン
	PubkeyAuthentication yes
	...
	# 必要あれば、パスワード禁止とか
	#PasswordAuthentication yes
	#PermitEmptyPasswords no
	...
	#コメントアウト
	#Match Group administrators
	#       AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys
	```


2. ユーザフォルダの  `.ssh\authorized_keys`にpubkeyを張り付ける。
3. `sshd`サービス再起動

	```powershell
	Restart-Service sshd
	```

4. (オプション) sshのデフォルトShellを powershell.exeに。
https://docs.microsoft.com/en-us/windows-server/administration/openssh/openssh_server_configuration

	```powershell
	New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -PropertyType String -Force
	```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75594/a90c272b-c9f3-2a40-dc62-0ac4154a361e.png)
Swift SDKでの機能ごとのユニークキーの違いについて

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

今回はNCMBの機能によって一覧データのユニークキーが異なる点を解説します。

## SwiftUIでの一覧表示について

SwiftUIで一覧表示を行う際にForEachをよく使うかと思います。

```swift
ForEach (memos, id: \.objectId) { memo in
    GridImageView(memo: memo)
}
```

NCMBから取得したデータに合わせてForEachを使う場合、オブジェクトによってユニークキーが異なるので注意が必要です。

## NCMBUser / NCMBObject / NCMBInstallation / NCMBPushの場合

機能としては次のデータになります。

- 会員管理
- データストア
- デバイストークン
- プッシュ通知

これらのオブジェクトのユニークキーは objectId になります。

```swift
ForEach (memos, id: \.objectId) { memo in
    GridDataView(memo: memo)
}
```

## NCMBFileの場合

ファイルストアの場合は fileName になります。

```swift
ForEach (memos, id: \.fileName) { memo in
    GridImageView(memo: memo)
}
```

## NCMBRoleの場合

権限管理を行うNCMBRoleの場合は roleName になります。

```swift
ForEach (roles, id: \.roleName) { role in
    GridRoleView(role: role)
}
```

## まとめ

ファイルストア、権限管理ではobjectIdが取得できませんので注意していください。idとして、それぞれファイル名やロール名を指定する必要があります。ファイルストアから写真を取得して一覧を作るのは良くある処理なので、覚えておくと便利です。

[イントロダクション (Swift) : クイックスタート | ニフクラ mobile backend](https://mbaas.nifcloud.com/doc/current/introduction/quickstart_swift.html)
[競プロ]いもす法実装【Java】

# いもす法を解きます

## いもす法とは
領域内の加算を効率的に行うアルゴリズムです。多次元でも行えて、便利なアルゴリズムとされています。累積和と関連があります。参考リンクは以下のとおりです。

https://imoz.jp/algorithms/imos_method.html



## 例題に合わせて解説
[ABC035 - C オセロ](https://atcoder.jp/contests/abc035/tasks/abc035_c)
ここでは例題に合わせて解説していきます。
今回、オセロのN個の駒が黒を上にして一列に置かれています。その後、Q回、ある駒からある駒までを裏返すという操作をします。その結果を一列で出力せよ、という問題です。

今回の制約からN,Qは200,000までで、例えばN=Q=200,000であったとし、各QにおいてN個の駒を裏返すという操作をするとすると、愚直に実装した場合、O(NQ)の計算量が必要となり、TLEとなってしまいます。
そこでいもす法の登場です。

今回は例題に合わせt１次元の領域について考えます。いもす法では、領域の両端のみ考え、**後で累積和を取った際に操作の結果の配列となる**よう調整しています。

以下の配列について考えます。
![スクリーンショット 2021-06-13 13.48.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504218/2e9dcfc6-c7b1-e4ac-e96e-b6491765c657.png)

Integerの配列を作成してすべて0（一度も操作されていない）とします。
ここで、配列の3~6番目に操作（今回の例題に合わせると、裏返し）があったとしましょう。
以下のように、3番目に1を、7番目（6+1番目）を　-1で更新します。
![スクリーンショット 2021-06-13 13.53.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504218/d6512b89-6746-9c0b-4d35-331d9e2e21c9.png)

この配列は、累積和を取ると以下のような配列になります。
3~6番目を裏返していますね。

![スクリーンショット 2021-06-13 13.54.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504218/a79d994d-43cc-cfc4-a351-07385a65f268.png)

このように、配列の操作する要素すべてにアクセスするのを最後に累積和するときだけにして、それ以外では始点と終点にしかアクセスしなくて良い、というのがいもす法の効率の良いところです。

ちなみに、今回の問題ではいもす法により該当の要素が何回裏返したのかという情報を保持しておいて、奇数回であれば白、偶数回であれば黒として答えを出しています。

## ACコード

``` java:Main.java
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt(); // 駒数
		int q = sc.nextInt(); // クエリ数

		int[] array = new int[n + 1]; // 駒の配列
		int[] ruisekiArray = new int[n + 1]; // 累積和とった配列

		for (int i = 0; i < q; i++) {
			int l = sc.nextInt() - 1; // 0-indexed
			int r = sc.nextInt() - 1; // 0-indexed

			// いもす法で、lに1を足してr+1から1を引く
			array[l]++;
			array[r + 1]--;
		}

		// arrayの累積和をとる
		ruisekiArray[0] = 0;
		for (int i = 1; i <= n; i++) {
			ruisekiArray[i] = ruisekiArray[i - 1] + array[i - 1];
		}

		// 偶数回裏返っていたら0, 奇数回であれば1とする
		for (int i = 1; i <= n; i++) {
			if (ruisekiArray[i] % 2 == 0) {
				ruisekiArray[i] = 0;
			} else {
				ruisekiArray[i] = 1;
			}
		}

		// 出力
		StringBuilder sb = new StringBuilder("");
		for (int i = 1; i <= n; i++) {
			sb.append(ruisekiArray[i]);
		}

		System.out.println(sb.toString());

	}
}

//
```
【Python】似ている文字列の類似度を調べる

#実行環境
Python 3.8.8
macOS Catalina v10.15.4

# インストール

今回は`python-Levenshtein`というライブラリを使用する

```python
% conda install python-Levenshtein
```

# 目的

**お茶**、**お〜いお茶**、**茶**のように似ている単語を見つける。

今回は`ラーメン、うどん、中華麺、麺、カレー、ドラえもん`の中からラーメンと似ている物を探す。

# 前処理

まず日本語の場合漢字から全てひらがなにしなければならない。

https://qiita.com/twrcd1227/items/df4946b8b7caae58db71

```python
>>> from pykakasi import kakasi
>>> word_list = ["ラーメン", "うどん", "中華麺", "麺", "カレー", "ドラえもん"]
>>> kks = kakasi()
>>> hira_word_list = []
>>> for word in word_list:
...     result = kks.convert(word)
...     new_word = ""
...     for res in result:
...         new_word += res['hira']
...     hira_word_list += [new_word]
... 
>>> hira_word_list
['らーめん', 'うどん', 'ちゅうかめん', 'めん', 'かれー', 'どらえもん']
```


# ゲシュタルトパターンマッチング

標準ライブラリ`difflib`を使って求められる。

```python
>>> import difflib
>>> for hira_word in hira_word_list:
...     similarity = difflib.SequenceMatcher(None, "らーめん", hira_word).ratio()
...     print(f"{hira_word}の類似度 : {similarity}")
... 
らーめんの類似度 : 1.0
うどんの類似度 : 0.2857142857142857
ちゅうかめんの類似度 : 0.4
めんの類似度 : 0.6666666666666666
かれーの類似度 : 0.2857142857142857
どらえもんの類似度 : 0.4444444444444444
```

中華麺よりドラえもんの方が類似度が高い。


# レーベンシュタイン距離

```python
>>> import Levenshtein
>>> # Levenshtein距離を標準化する
>>> def lev_dist(str1, str2):
...     return 1 -  (Levenshtein.distance(str1, str2) / max(len(str1), len(str2)))
... 
>>> for hira_word in hira_word_list:
...     similarity = lev_dist('らーめん', hira_word)
...     print(f"{hira_word}の類似度 : {similarity}")
... 
らーめんの類似度 : 1.0
うどんの類似度 : 0.25
ちゅうかめんの類似度 : 0.33333333333333337
めんの類似度 : 0.5
かれーの類似度 : 0.0
どらえもんの類似度 : 0.4
```

**中華麺**の類似度が0.3と低いのに対して、**ドラえもん**は0.4ある。

# ジャロ・ウィンクラー距離

```python
>>> for hira_word in hira_word_list:
...     similarity = Levenshtein.jaro_winkler('らーめん', hira_word)
...     print(f"{hira_word}の類似度 : {similarity}")
... 
らーめんの類似度 : 1.0
うどんの類似度 : 0.5277777777777778
ちゅうかめんの類似度 : 0.611111111111111
めんの類似度 : 0.0
かれーの類似度 : 0.5277777777777778
どらえもんの類似度 : 0.6333333333333333
```

**めん**の類似度が0である一方、**ドラえもん**の類似度が0.633もある
ジャロ・ウィンクラー距離は位置はあまり関係しない。


#　結果、考察

中華麺よりドラえもんの方がラーメンに似ている。

ドラえもんより中華麺の方が類似度を高くするためにまず形態素解析で`中華　＋　麺`とした方がいいと思う

そもそもラーメンが麺に似ているのはたまたまで、ラーメンがスパゲティだったら麺に似ていない。
NCMBのファイルストアで取得したデータを一覧表示しようとして `Fatal error: each layout item may only occur once: file SwiftUI, line 0` が発生した場合の対処法

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

今回はSwift SDKを使っていて、ファイルストアから取得した写真の一覧を表示しようとした際に `Fatal error: each layout item may only occur once: file SwiftUI, line 0` というエラーが出た場合の対処法です。SDKのバージョンは1.2.0になります。

## ファイルストアから一覧を取得する

まずファイルストアから写真一覧を取得する処理についてです。基本的には次のように書きます。 `NCMBFile.query` でファイルストアを検索するためのNCMBQueryが取得できます。後は検索条件を指定して実行するだけです。

```swift
var query = NCMBFile.query
query.findInBackground(callback: { result in
    switch result {
        case let .success(array):
            self.photos = array
        case let .failure(error):
            print("取得に失敗しました: \(error)")
    }
})
```

そして、この取得した `photos = [NCMBFile]` を使って、SwiftUIでForEachを実行します。この時の注意点として、id を fileName とします。データストアではobjectIdですが、ファイルストアの場合はユニークなキーは fileName になります。

```swift
ForEach (photos, id: \.fileName) { memo in
    GridImageView(photo: photo)
}
```

しかし、このまま実行すると `Fatal error: each layout item may only occur once: file SwiftUI, line 0` というエラーが発生します。原因は photos[0].fileName が nil のためです。

そこで打開策として、データ取得時に次のようにします。マップとして入っているfileNameフィールドの値を、NCMBFileのfileNameプロパティに入れ直します。

```swift
var query = NCMBFile.query
query.findInBackground(callback: { result in
    switch result {
        case let .success(array):
            for file in array {
                if let fileName: String = file["fileName"] {
                    file.fileName = fileName
                }
            }
            self.photos = array
        case let .failure(error):
            print("取得に失敗しました: \(error)")
    }
})
```

これでForEachのエラーが出なくなります。

## まとめ

1.2.0ではエラーになりますが、こちらは後日アップデートで対応する予定です。現状のモンキーパッチ的な対応になりますが、エラーが出た際には上記コードで対応してください。

[ファイルストア (Swift) : 基本的な使い方 | ニフクラ mobile backend](https://mbaas.nifcloud.com/doc/current/filestore/basic_usage_swift.html)
STM32F767と秋月シリアル7セグで3分タイマー SPI


x Mbed2のリビジョンは、172
x Mbedでのボード設定は、NUCLEO-F767ZI
x 赤色７セグメントＬＥＤシリアルドライバモジュール　完成品
x OSL10564-74HC595-R M-12642

説明
文字を文字パターンに変換する
64は、@の開始位置です。
7セグメントの文字パターンに変換
変換範囲は、32文字で5ビット分

メイン関数
main()
いろいろ初期化
1から3までを1分毎に7セグに表示して
無限ループで停止する



```c++

#include "mbed.h"

//*          *****  *****  
//*         *       *    * 
//*         ******  *    *
//*         *       *    *
//*         *       *    *
//********   *****  *****

#define swclk1  PA_5    //A4
#define test01  PA_6
#define swdio1  PA_7    //A6
#define en1     PA_4    //A3

SPI spi( D11 , D12 , D13); // mosi, miso, sclk //767
DigitalOut en( D10 ); //767

//SPI spi( swdio1 , test01, swclk1); // mosi, miso, sclk //010
//DigitalOut en(en1); //010

char seg[32] = {
   0x00 , //0 @ -> ' '
   0x77 , //1 A  o
   0x7c , //2 B     　combined use "6"
   0x39 , //3 C
   0x5e , //4 D
   0x79 , //5 E  o
   0x71 , //6 F
   0x3d , //7 G
             
   0x76 , //8 H  o
   0x06 , //9 I    　combined use "1"
   0x1e , //10 J
   0x75 , //11 K 
   0x38 , //12 L  o
   0x15 , //13 M
   0x37 , //14 N  o
   0x3f , //15 O  o　combined use "0"
              
   0x73  , //16 P
   0x67  , //17 Q　combined use "9"
   0x50  , //18 R
   0x6d  , //19 S　combined use "5"
   0x78  , //20 T
   0x3e  , //21 U
   0x1c  , //22 V
   0x2a  , //23 W  o
   0x64  , //24 X
               
   0x6e  , //25 Y
   0x5b  , //26 Z　combined use "2"
   0x4f  , //27 [  --> "3"
   0x66  , //28 \  --> "4"
   0x27  , //29 ]  --> "7"
   0x7f  , //26 ^  --> "8"
   0x08    //31 _
};


#define s60()   for(ii=0;ii<60;ii++)wait_ms(1000);

int main() {

    spi.format(8,0);
    spi.frequency(1000000);

    en=0;

    int ii; //ループカウンター

    //0分
    spi.write(seg['O'-64]);en=1;en=0;
    s60();

    //1分
    spi.write(seg['I'-64]);en=1;en=0;
    s60();

    //2分
    spi.write(seg['Z'-64]);en=1;en=0;
    s60();

    //3分
    spi.write(seg['['-64]);en=1;en=0;

    while(1){} //無限ループ

}//main

//容量削減
//void error(const char* format, ...){}



```
【Javascript】forEach関数について-学習ノート1

# 初めに
javascriptのforEach()関数について学習した内容のoutput用記事です。

※内容に間違いなどがある場合はご指摘をよろしくお願いします。
※こちらの記事はあくまでも個人で学習した内容のoutputとしての記事になります。

前回の記事：https://qiita.com/redrabbit1104/items/c3501e087f54facc52fe

# forEach()関数
関数を引数にする関数（高階関数）の一つ。配列の要素を一つひとつに対して関数の中で記述した特定の処理を行うことができる。

# for of文と比較しながら使ってみる
forEach()関数を使ってchangesという配列の各要素の値を２倍にしコンソールに表示してみます。

```javascript
const changes = [100, 400, -300, 120, -50, -330, 1400, 500];

changes.forEach(function (change) {
  console.log(change * 2);
});
```
配列の各要素の値が２倍になって出力されました。
![スクリーンショット 2021-06-21 7.24.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/dbeb2fb2-aa4c-408a-a386-5d5462591966.png)

これはfor of文を使えば同じような結果が得られます。

```javascript
for (const change of changes) {
  console.log(change * 2);
}
```

for ofではentries()メソッドを使って、配列の要素をindexとvalueで分けて処理することができます。

```javascript
for (const [i, change] of changes.entries()) {
  console.log(`${i} : ${change * 2}`);
}
```
![スクリーンショット 2021-06-21 7.32.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/7043cab1-de58-9fc0-a0ea-0238bfc24f98.png)

forEach()関数を使う場合、for of文と同じ処理ができますが引数の順番が「value, index, array」になるので要注意です。また、第３引数にarray(配列）を取ることができます。

```javascript
changes.forEach(function (change, index, array) {
  console.log(`${array} // ${index} : ${change * 2}`);
});
```
![スクリーンショット 2021-06-21 7.40.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/815497cf-006e-469b-06f9-9aeb1cb14f3e.png)

for of文とforEach()関数の違いは色々ありますが、for ofの場合break,continue,returnの３種類の制御文が使えるのに対し、forEach()では使えないところです。

```javascript
for (const change of changes) {
  if (change > 0) {
    console.log(change * 2);
  } else {console.log('終了');
  break;}
};
```
![スクリーンショット 2021-06-21 7.50.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/e080fe4f-0067-588d-f463-a2b85d638eb6.png)
同じような処理をforEach()関数でやろうとすると、

```javascript
changes.forEach(function (change) {
  if (change > 0) {
    console.log(change * 2);
  } else {console.log('終了');
  break;}
});
```
構文エラーが出てしまいます。forEach()関数は最初から最後まで途切れずに処理を行われるようになっていますので、途中で処理を制御したい場合にはfor of文を使うべきです。
![スクリーンショット 2021-06-21 7.51.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/ba2431b8-ff87-d3a4-ab4b-dc03fc3e4eba.png)

# 参考サイト
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
http://var.blog.jp/archives/74672042.html
Railsでブログシステムを作りたいPart1

#1.なぜやるのか

・Web系企業に未経験で転職し一ヶ月たち、技術書インプットメインの自己研鑽に飽きた（とゆうか身についてない感じがした）

・もともとブログを運営したいと思っていたが、せっかくならWordPressを使わない（会社でつかっているRails）でやりたい

というモチベーションです。そのため、Railじゃないと実現できない機能があるから使うわけではなく、あくまでもRailsを勉強したいというのが先行しています。


#2.実現したいシステム
###概要
旅行先や飲食店、遊んだ場所を紹介するブログを作りたいと思っています。
想定読者は日本人と台湾人です。僕の彼女が台湾人なので台湾中国語対応のブログにしたいと思っています。

###欲しい機能
・日本地図や台湾地図で記事をソート
・地図表示
・２ヶ国語対応　
・リッチテキストエディター
・バックヤード(管理者画面)
・pc+sp対応
等々

#3.開発環境(予定含む)
ruby 3.0
rails 6.1.3
MySQL
AWS(本番環境インフラ)←まだちゃんと調べてないのでざっくりです
bootstrap
rspec
circle ci


#4.やったこと
・Mysql初期設定
・localhost:3000立ち上げ
・githubのリモートリポジトリと連携
・リッチテキストエディター導入(ActionTextで簡単にできた)

いつかsqliteだと困る時が来るだろうと思い、最初からMySQLにしました。セキュリティ設定することも知らずに進めていてちょっと時間を無駄にしましたが、下記載の「つまずいた点メモ」の記事通りやればなんてことなかったです。

無事localhost:3000でYay！が確認できたのち、以下の記事を参考にリッチテキストエディターを導入することができました。
[【Rails】Action Textの基本情報と実装方法](https://www.autovice.jp/articles/36)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1010233/560930b9-13a5-df05-1732-691e194fdb1c.png)

しかし、上の画像にも書いたとおり「Create Article」をしてもContentが表示されません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1010233/c3303210-b179-5944-dd76-b47f3173eb5d.png)

と思ったら以下のようにメソッドのコピーするところを間違えていたようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1010233/7c4a86b7-4e45-cdf5-8aa4-a1d41a9a57d7.png)

見返すと参考にした記事でscaffoldを作成するときにtitleしか設定してないんですね。

```
rails g scaffold Article title:string
```

リッチテキストエディタを作る過程で、article.rbにcontentにリッチテキストが書けるように設定してました。

```ruby
class Article < ApplicationRecord
  # 以下を追記
  has_rich_text :content
end
```

そのため、articles_controller.rbに作成されているarticle_params（保存を許可するストロングパラメータ）メソッドにcontentを追加する必要があったんですね。scaffoldで作成されるデータやメソッドを把握してなかったので、初歩的なところでバグが出てました。

###5.まとめ

今回はリッチテキストエディタが使えるところまでやりました。
やはりコードを書くのは楽しいと思ったので、書籍での学習におりまぜてアウトプットしていきたいと思います。


#6.つまずいた点メモ
###mysql2のgemがインストールできない
以下の記事を参考(紆余曲折しましたが結局この記事に全部まとまっていた)にインストールできました。

[【Rails/MySQL】RailsにMySQLを導入する方法【プログラミング学習149日目】](https://qiita.com/fuku_tech/items/a380ebb1fd156c14c25b)

```
In Gemfile:
  mysql2
         run  bundle binstubs bundler
Could not find gem 'mysql2 (~> 0.5)' in any of the gem sources listed in your Gemfile.
```

###Rails６環境起因のエラー周り

[Rails6 開発時につまづきそうな webpacker, yarn 関係のエラーと解決方法](https://qiita.com/NaokiIshimura/items/8203f74f8dfd5f6b87a0)

###データベースを作成していなくてサーバーが立ち上がらないエラー

```
rails db:create
```
[ActiveRecord::NoDatabaseErrorが出た時の対処法](https://rails-ambassador.herokuapp.com/debugs/NoDatabaseError)
collection_select

collection_selectのメソッドを使うことでデータをプルダウンを表示させることができる。
引数が第一から第五までありそれぞれの役割は以下の通り。

第一引数に保存したいカラム名を記述。
第二引数に配列データを指定する。（この際、クラス名の命名規則があるのでアッパーキャメルで記述）
第三引数に表示する際に参照するカラム名を記述。
第四引数に実際に表示させたいカラム名を記述
第五引数にオプションの指定。（include_blankという値のない選択肢を先頭にするオプションもある）

記述方法の例としては以下の通り。

```ruby
<%= form.collection_select(保存されるカラム名, オブジェクトの配列, カラムに保存される項目, 選択肢に表示されるカラム名, オプション, htmlオプション) %>
```

実際に記述したコードは以下の通り。
例えば発送地域などを表示させたい場合はまずモデルにプルダウンに表示させたい情報を記述。

```ruby
class DeliveryArea < ActiveHash::Base
  self.data = [
    { id: 1, name: '---' }, 
    { id: 2, name: '北海道' }, 
    { id: 3, name: '青森県' }, 
    { id: 4, name: '岩手県' },
    { id: 5, name: '宮城県' }, 
    { id: 6, name: '秋田県' }, 
    { id: 7, name: '山形県' },
    { id: 8, name: '福島県' }, 
    { id: 9, name: '茨城県' }, 
    { id: 10, name: '栃木県' },
    { id: 11, name: '群馬県' }, 
    { id: 12, name: '埼玉県' }, 
    { id: 13, name: '千葉県' },
    { id: 14, name: '東京都' }, 
    { id: 15, name: '神奈川県' }, 
    { id: 16, name: '新潟県' },
    { id: 17, name: '富山県' }, 
    { id: 18, name: '石川県' }, 
    { id: 19, name: '福井県' },
    { id: 20, name: '山梨県' }, 
    { id: 21, name: '長野県' }, 
    { id: 22, name: '岐阜県' },
    { id: 23, name: '静岡県' }, 
    { id: 24, name: '愛知県' }, 
    { id: 25, name: '三重県' },
    { id: 26, name: '滋賀県' }, 
    { id: 27, name: '京都府' }, 
    { id: 28, name: '大阪府' },
    { id: 29, name: '兵庫県' }, 
    { id: 30, name: '奈良県' }, 
    { id: 31, name: '和歌山県' },
    { id: 32, name: '鳥取県' }, 
    { id: 33, name: '島根県' }, 
    { id: 34, name: '岡山県' },
    { id: 35, name: '広島県' }, 
    { id: 36, name: '山口県' }, 
    { id: 37, name: '徳島県' },
    { id: 38, name: '香川県' }, 
    { id: 39, name: '愛媛県' }, 
    { id: 40, name: '高知県' },
    { id: 41, name: '福岡県' }, 
    { id: 42, name: '佐賀県' }, 
    { id: 43, name: '長崎県' },
    { id: 44, name: '熊本県' }, 
    { id: 45, name: '大分県' }, 
    { id: 46, name: '宮崎県' },
    { id: 47, name: '鹿児島県' }, 
    { id: 48, name: '沖縄県' }
  ]

  include ActiveHash::Associations
  has_many :items
end
```

次にViewsのnew.html.erbに冒頭で説明した手順に沿って記述。

```ruby
        <%= f.collection_select(:delivery_area_id, DeliveryArea.all, :id, :name, {}, {class:"select-box", id:"item-prefecture"}) %>
```

このように記述することでブラウザ上でプルダウンが表示される。
Delphi: Resource Hacker を使う（そしてバイナリファイル比較など）

http://www.angusj.com/resourcehacker/

https://ja.wikipedia.org/wiki/Resource_Hacker

いうまでもなく、のところとして自作のExeに対して使うことが妥当。(以下 Wikipedia 引用)
> コンパイルしたファイルに余計なリソースが含まれている場合、そのリソースを削除することで、実行ファイル等の余分なファイルサイズを削ることができる。また、アイコンを自由に置き換えることができるため、コンパイル元のソフトウェアでアイコンが指定できない場合、Resource Hackerを利用して置き換える。また、通常では変更できないプログラムの内容の変更をするために利用する。

## Resource Hacker で Project1.exe を覗いたところ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/4d8c2b04-202c-d1c7-d4ca-e4c6cb41e583.png)


### Project1.exe サンプル 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/4a80743c-e454-1055-a87e-fbc042d921a5.png)

```pascal
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  Showmessage('Hello World!');
end;

end.
```

## 他、バイナリを比較、解析するツール

https://peryaudo.hatenablog.com/entry/20110105/1294209734

https://www.softpedia.com/get/Programming/Debuggers-Decompilers-Dissasemblers/DeDe.shtml


https://freebsd.sing.ne.jp/tool/03/08/03.html

https://www.dcom-web.co.jp/lab/etc/different_bitmap

https://forest.watch.impress.co.jp/docs/news/749354.html

https://www.zynamics.com/software.html

BinDiffはIDA（アイダ）のプラグイン

https://www.hex-rays.com/products/ida/support/download_freeware.shtml

で、IDAはリバースエンジニアリングのデファクトスタンダードらしい。

https://www.atmarkit.co.jp/ait/articles/1108/22/news110.html

しかし商用利用NGとのことなので代替品を探す。

https://error4hack.com/best-ida-pro-alternatives/

https://github.com/NationalSecurityAgency/ghidra


以上メモのみ。
Nuxt　localhostで立ち上げたアプリをiPhoneで起動させる方法

# Nuxtのローカルホストで立ち上げたアプリをiPhoneで起動させる
Nuxtのローカルホストで立ち上げたアプリをモバイル端末で開こうとしたら少し詰まったのでメモ

## 環境
macOS BigSur 11.01
iPhone Xr iso14.2

## Nuxt側の設定
nuxt.config.jsファイルに以下を追記

``` nuxt.config.js

  server: {
    host: '0.0.0.0', // デフォルト: localhost,
    timing: false,
  },
```

## Macの設定
設定からファイアウォールをオフにする(セキュリティ的観点で見てテストが終わったらオンにしましょう）
![スクリーンショット 2021-06-24 5.10.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/662481/bdc147a1-98ca-1590-6275-d3d9653f6603.png)


##　iPhoneでアプリを起動
`npm run dev` or `yarn dev` した際に表示される以下のものをコピ<br>私の環境では`http://192.168.101.25:3000/`コピーするか手入力してsafariで開く
![スクリーンショット 2021-06-24 5.16.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/662481/fd11207f-f45f-09b3-146a-aad68ae0148e.png)
すると以下のように開くことができる
![IMG_4400.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/662481/3eeb7341-b9de-4001-a2e1-8f7bcc6d7803.jpeg)
LPICレベル1を勉強しているあなたへ - システムを再起動させる3つの方法 -

■rebootコマンドを実行する

■「init 6」または「telinit 6」コマンドを実行する
ランレベルを6に変更するとシステムが再起動します。

■shutdownコマンドを使用する

引用元：https://mondai.ping-t.com/question_subjects/31/question_sessions/3984558/progressing_questions/61162676?result=true
[Bootstrap4]mx-autoでブロックでセンタリングする

## 環境

```
bootstrap: 4.6.0
```

## 本題
[公式ドキュメント](https://getbootstrap.jp/docs/4.3/utilities/spacing/)では`mx-auto`について以下のように書かれています。

> 固定幅のブロックレベルのコンテンツを水平にセンタリングする

ですから、固定幅を持ったブロックの下の要素に`mx-auto`と指定することで水平にセンタリングすることができます。

```
<div class="mx-auto">
 (センタリングされる要素)
</div>
```
【Python】漢字を平仮名やローマ字に変換する


# 概要

Pythonで漢字をひらがなに変換する方法を調べてみた。

# 実行環境

Python 3.8.8
macOS Catalina v10.15.4

# インストール


**pykakasi**を使うと漢字をひらがなやローマ字にすることができる。
**anaconda**でインストールする場合

```:terminal
% conda search pykakasi
```


**pip** の時は

```:terminal
% pip install pykakasi
```

# 実際に変換する

```python
>>> from pykakasi import kakasi
>>> # インスタンスの作成
>>> kks = kakasi()
>>> word = "僕は未来から来た猫型ロボット"
>>> result = kks.convert(word)
>>> result
[{'orig': '僕は', 'hira': 'ぼくは', 'kana': 'ボクハ', 'hepburn': 'bokuha', 'kunrei': 'bokuha', 'passport': 'bokuha'}, {'orig': '未来', 'hira': 'みらい', 'kana': 'ミライ', 'hepburn': 'mirai', 'kunrei': 'mirai', 'passport': 'mirai'}, {'orig': 'から', 'hira': 'から', 'kana': 'カラ', 'hepburn': 'kara', 'kunrei': 'kara', 'passport': 'kara'}, {'orig': '来た', 'hira': 'きた', 'kana': 'キタ', 'hepburn': 'kita', 'kunrei': 'kita', 'passport': 'kita'}, {'orig': '猫型', 'hira': 'ねこがた', 'kana': 'ネコガタ', 'hepburn': 'nekogata', 'kunrei': 'nekogata', 'passport': 'nekogata'}, {'orig': 'ロボット', 'hira': 'ろぼっと', 'kana': 'ロボット', 'hepburn': 'robotto', 'kunrei': 'robotto', 'passport': 'robotto'}]
>>> result[0]
{'orig': '僕は', 'hira': 'ぼくは', 'kana': 'ボクハ', 'hepburn': 'bokuha', 'kunrei': 'bokuha', 'passport': 'bokuha'}
>>> # ひらがなにする
>>> for converted_word in result:
...     print(f"{converted_word['hira']}", end ="")
... 
ぼくはみらいからきたねこがたろぼっと
>>> # カタカナにする
>>> for converted_word in result:
...     print(f"{converted_word['kana']}", end ="")
... 
ボクハミライカラキタネコガタロボット
>>> # ローマ字にする
>>> for converted_word in result:
...     print(f"{converted_word['hepburn']}", end ="")
... 
bokuhamiraikarakitanekogatarobotto
```
条件分岐を整理する

親記事 : https://qiita.com/Regpon/items/1116679adadd8fb76f3f

https://qiita.com/Regpon/items/1116679adadd8fb76f3f

# 判断や処理のロジックをメソッドへ

顧客の区分に応じて値段を変えるロジックがあるとする。
例として顧客区分が学生だった場合のロジックを考えてみる。

```Java
if (customerType.equals("student")) {
  price = basePrice * 0.7;
}
```

このようなロジックにすると、学生かどうかの判定、学生だった場合値段がどのようなロジックで生まれるのかがわかりにくいのと、管理がしにくくなる。
このロジックの変更を加える際、果たして本当にこの部分の変更だけで問題ないのか、他に同じようなロジックを持ってしまていないか考えなくてはならない。
そこで、学生かどうかを判断するロジック、学生だった場合の値段を決めるロジックを切り出し、再利用可能なメソッドに置き換えることを検討する。

すると以下のようになる。

```Java
if (isStudent(customerType)) {
  price = studentPrice(basePrice);
}

boolean isStudent(Customertype customerType) {
  return customertype.equals("student");
}

int studentPrice(int price) {
  return price * 0.7;
}
```

このようにしておくと、ごちゃごちゃと書かれた計算式や条件式を変更するよりも安全で安心感がある。

# else句はなるべく無くす

学生や幼児など、顧客の区分に応じて様々な料金体系があった場合、条件分岐が多数生まれる。

```Java
Price price() {
  Price result;
  if (isStudent()) {
    result = studentPrice(); // 学生料金
  } else if (isToddler()) {
    result = toddlerPrice();  // 幼児料金
  } else {
    result = adultPrice();  // 成人料金
  }

  return result;
} 
```

しかし、このような実装はガード節という早期リターンする書き方でelse句を無くすことができる。

```Java
Price price() {
  if (isStudent()) return studentPrice(); // 学生料金
  if (isToddler()) return toddlerPrice();  // 幼児料金
  return adultPrice();  // 成人料金
} 
```

コードでelse句を見つけたらガード節に書き換えてelse句を無くすことができないか検討することを心がけると良い。
このようにすると新たな区分（例えば70歳以上の高齢者など）を追加した場合でも、追加が容易になる。

### 文献

本記事は [現場で役立つシステム設計の原則 変更を楽で安全にするオブジェクト指向の実践技法 　著：増田 亨](https://www.amazon.co.jp/%E7%8F%BE%E5%A0%B4%E3%81%A7%E5%BD%B9%E7%AB%8B%E3%81%A4%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E8%A8%AD%E8%A8%88%E3%81%AE%E5%8E%9F%E5%89%87-%E5%A4%89%E6%9B%B4%E3%82%92%E6%A5%BD%E3%81%A7%E5%AE%89%E5%85%A8%E3%81%AB%E3%81%99%E3%82%8B%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91%E3%81%AE%E5%AE%9F%E8%B7%B5%E6%8A%80%E6%B3%95-%E5%A2%97%E7%94%B0-%E4%BA%A8/dp/477419087X) を読んで(なるべく)自分の言葉でまとめたものです。

興味を持っていただけたらこちらの本を読んでみていただけたらと思います。(勝手に宣伝)
LPICレベル1を勉強しているあなたへ - 今更ながらlsコマンドとは -

lsコマンドは 

「list directory contents」

 の略でして、 「エルエス」 と言う読み方をします。
 lsコマンドで出来ることはディレクトリの中にあるコンテンツを
一覧表示する時や現在のファイル状況 
(書き込み権限や不可視ファイルなど) 
を確認する際によく使われます。