OmniAICreator/Qiita-1.07M huggingface dataset:
【Flutter】TimeOfDay型をshared_preferencesで保存する

# はじめに
最近、Flutterで`TimeOfDay`型の値を保存するのに苦労して、日本語の記事もあんまり見かけなかったので記事にします！
ちなみにtimePickerで選んだ時刻を保存するのに使いました。

# 手順１　TimeOfDay型をString型で保存する
現時点で`shared_preferences`で標準で保存できる方は以下の五つ
　・`int`型
　・`double`型
　・`string`型
　・`bool`型
　・`list`型
となっており`TimeOfDay`型を保存するにはひと工夫しないといけません。

そこでまず、`TimeOfDay`型の値を`String`型に変換します。
`String`型から`TimeOfDay`型に直接変換できないため、`String`→`DateTimeみたいなフォーマットのString型`→`TimeOfDay`というふうに変換していきます。

`TimeOfDay`型を`String`型に変換したものを`DateTime`型っぽい`String`型に変換するんですが、`TimeOfDay`型は時と分を持っていて、`DateTime`型は年、月、日を持っているため少し工夫します。

```dart:store_TimeOfDay.dart
//変換の際に使うDATETIME型やつ
  DateTime now = DateTime.now();

  //タイムピッカーデフォルトの変数
  TimeOfDay _selectedTime = TimeOfDay(hour: 10, minute: 00);

  // String型を保存する関数を用意
  _saveTime(String key, String value) async {
    var prefs = await SharedPreferences.getInstance();
    prefs.setString(key, value);
  }

  ------------------------------------------------------

if (取得した値 != null) {
        setState(() {
          _selectedTime = 取得した値;
          _saveTime('time',  DateTime(
            now.year,//DateTime
            now.month,//DateTime
            now.day,//DateTime
            _selectedTime.hour, // TimeOfDay
            _selectedTime.minute, //TimeOfDay
          ).toString());
          // これで　2022-06-22 10:00:00.000　こんな感じになる
        });
      }
```
# 手順２　保存したStringの値取得する際にTimeOfDayに変換する
```dart:store_TimeOfDay.dart
_restoreValues() async {
    var prefs = await SharedPreferences.getInstance();

    setState(() {
      //保存した`String`型の値を新しい変数に入れる
      String stringTimeData = prefs.getString('time') ?? "2022-06-22 10:00:00.000";
      //上のstringTimeDataをTimeOfDay型に変換する
      _selectedTime = TimeOfDay.fromDateTime(
          DateTime.parse(stringTimeData));
    });
  }

void initState() {
    super.initState();
    _restoreValues(); //次回のget
  }
```

# おまけ
timePickerで選択させた時刻をテキストで表示させる場合（例）↓
```dart:時刻表示.dart

String timeText = ''; //時刻表示につかうString型の変数

//選択した時刻のテキスト
    String _getTimeText() {
      if (_selectedTime == null) {
        return '10:00';
      } else {
        var hours = _selectedTime.hour.toString();
        var minutes = _selectedTime.minute.toString().padLeft(2, '0');

        if (hours == '12') {
          hours = '24';
        }

        if (hours == '0') {
          hours = '12';
        }

        timeText = '$hours : $minutes';


        return timeText;
      }
    }
```

timePickerのinitialTimeに`selectedTime.hour`,`_selectedTime.minute`を指定すると前回選択した時刻から時刻の選択をさせることもできますね

お疲れ様でした。
【GitHub】草の偽造方法

# はじめに
「草を生やす事が目的になってしまっては意味がない」
ごもっともな意見だと思います。

正直、草なんて完全に自己満です
グラフに穴が開いて悲しくて寝れないって方だけ試してみてください。

良くないとは思うのでどうしてもって時だけこっそり使ってください

# 方法
```
cd ローカルリポジトリのパス
git add -A
git commit -m "過去の日付でコミット" --date="Mon Jun 27 16:22:34 2022 +0900"
git push origin main
```

# 解説
`date`はこのように指定します
```
--date="曜日 月 日 時間 年 +0900"

↓ 2022年6月27日(月)16時22分34秒に指定する場合 ↓

--date="Mon Jun 27 16:22:34 2022 +0900"
```

|曜日|指定|
|:-:|:-:|
|日曜日|Sun|
|月曜日|Mon|
|火曜日|Tue|
|水曜日|Wed|
|木曜日|Thu|
|金曜日|Fri|
|土曜日|Sat|

|月|指定|
|:-:|:-:|
|1月|Jan|
|2月|Feb|
|3月|Mar|
|4月|Apr|
|5月|May|
|6月|Jun|
|7月|Jul|
|8月|Aug|
|9月|Sep|
|10月|Oct|
|11月|Nov|
|12月|Dec|
【C#】コンソールアプリケーション起動時にアプリケーションのウィンドウを非表示にしたい


```csharp
using System.Diagnostics;
using System.Runtime.InteropServices;

int SW_MINIMIZE = 0;
long WinMinHandle = 0;

[DllImport("user32.dll")]
static extern int ShowWindow(IntPtr handle, int command);

var p = Process.GetCurrentProcess();
WinMinHandle = ShowWindow(p.MainWindowHandle, SW_MINIMIZE);

```
IoCとDI

### IoCとDI

#### IoC（制御の反転）
制御の流れを伝統的な方式と逆に変えること。Aオブジェクトの中にB、Cオブジェクトがあるとしましょう。
* 伝統的な方式は開発者がAオブジェクト内にB、Cオブジェクトを直接作る方式
* IoCは、Aオブジェクトでsetterを使用して外部からB、Cオブジェクトを生成して注入させる方式。（DI）
→プログラムの流れを開発者が制御せず、プログラム、正確に言えばSpring containerが管理することで、開発者は複雑なプログラムの流れをSpring containerに任せ、ロジックにすることに集中して作業の効率を高めることができる。
 
#### DI（依存性の注入、依存オブジェクト注入）
使用するオブジェクトを直接生成するのではなく、Beanの情報を元にContainerが自動的に注入してくれることで、クラス間の分離が行われ、再利用性の高いコードとなる。

#### 依存オブジェクトの自動注入(Automatic Dependency Injection)
依存オブジェクトの自動注入は、Spring containerが自動的に依存オブジェクトを探し、そのオブジェクトに必要な依存を注入することである。

依存オブジェクトの注入方法には@Autowired、@Resource、および@Injectなどのアノテーションがあるが、オブジェクトを探し出す方法が異なる。

1. @Autowired 
Springでサポートされているアノテーションで、注入しようとするオブジェクトの**タイプ**が一致するBeanを確認、オブジェクトを自動的に注入します。タイプが存在しない場合は、@Autowiredにある**属性名**が一致するBeanをContainerで探す。それでもなかった場合は **@Qualifier アノテーション**の有無を探し、そのアノテーションが付いた属性に依存性を注入する。

2. @Resource
Javaでサポートされているアノテーションで、まず属性の**名前**を探す。なければ**タイプ**、それもなければ **@Qualifierアノテーション** の有無を探し、そのアノテーションがついた属性に依存性を注入する。

3. @Inject
Javaでサポートされるアノテーションで、**タイプ**の一致を基準に探し、なければ **@Qualifierアノテーション**、最後に**名前**を探して依存性を注入する。 @Injectを使用するには、mavenまたはgradleにjavaxライブラリの依存関係を追加する必要がある。

4. @Qualifierとは
先ほど3つのアノテーションは順番は違うがみんなタイプが一致するBeanを検索するとのことだったが、もし、同じタイプを持つBeanオブジェクトが2つ以上ある場合はどうなるか。注入対象が1つでなければならないが、2つ以上のBeanが存在するせいで注入するときに使用するオブジェクトを選択できないため、Exceptionというエラーが発生することになる。この問題を解決するために使用するのが@Qualifierアノテーション。@QualifierはBeanを指定することができる。

|  |@Autowired | @Resource  | @Inject |
|:-:|:-:|:-:|:-:|
| 使用    | Spring  | Java  | Java  |
| 検索（適用）| Type→Name→@Qualifier | Name→Type→@Qualifier | Type→@Qualifier→Name |
停電

ここ10年で我が家の停電は二回ほどあり、一度は落雷によるもので、もう一度は今年の3月の地震によるものでした。

今年は電力供給がひっ迫していて、回避できないと停電の可能性があるのかもしれません。

我が家のおうちモニターはスマートメーターなどのデータをsqlite3で/tmpのメモリディスクに置いているので、停電するとすべてのデータが消えてしまいます。

データーは2週間分とってありますが、スマートメーターと気温のデーター以外は当日と昨日の分しかデーターの利用はありません。

おうちモニターをメンテするときはdbファイルをtftpで他のサーバにバックアップしてメンテ後にリストアしてます。

3月の停電ではVPNの設定がアドホックだったためVPNで入れなくなりました。教訓でアドホックな設定は廃止して、またst1なntpdは自立して再起動するようにしました。

ZRouter.orgのrootfsはread onlyで書けるところはメモリディスクの/tmpくらいになります。

停電の対策のために定期的にUSBメモリに保存しておくとか、停電を検知して、USBメモリに保存するなどの方法が考えられます。前者は確認が簡単ですが、後者は大変な気がします。どちらにしても大掛かりです。

flashにread writeなfsを作ると寿命がありますし、インターネットへのバックアップも面倒です。我が家はインターネットが消滅しても自立して稼動できるネットワークを目指しています。

無停電電源などの方法はコスト的に現実的ではありません。無停電電源にも寿命があります。

現実的にはFATなSDに一日一度書くとかになると思います。これであれば100年くらいは持つのではないでしょうか。

おうちモニターのモジュールはリチウムイオン(18550)一本で停電は乗り切れると思われますが、リチウムイオンで火事でも起こしたらもともこうもありません。

昔から恐いのは、「地震・雷・火事・親父」と言いますからね。

個人利用だし5年に1度の障害にコストをかけるのも馬鹿らしいので、おそらくこのままだと思います。

停電は給湯のコントローラの時間がリセットされるのでも確認できます。
長期インターン体験記


### 自己紹介
- 現在、関東国立大学に通う２年生です。
- 高校時代にpythonの基本的な内容を一通りさらいましたが、プログラミングを使ってしたいこと、ゴールのようなものがなくてモチベーションを無くし離れていきました。

### 長期インターンに応募した理由
私が長期インターンに応募した理由は大きく以下の二つが挙げられます。

- スキルのつくバイトとして
一つ目の理由としては、スキルのつきそうなバイトを探していたからです。元々、お金を稼ぐ為だけにバイトに時間を費やしたくなかったので、何かしらのスキルが身につくバイトをしたいと思っていました。長期インターンはこの点で非常に魅力的だったので、スキルのつくバイト感覚で応募しました。

- 進学選択にあたって
もう一つの理由としては、単純にプログラミングに興味があったからです。このインターンを見つけた頃、進学する学部・将来の職業について考えている中で、選択肢が多すぎて悩んでいました。頭で考えていても埒が明かないので興味のあったプログラミング分野に少しだけ足を踏み入れようと思い、このインターンの応募に至りました。

### 具体的な業務内容
- 基本的にうちの会社は他社から受諾した依頼内容に沿った製品・成果を報告するという形を取っています。インターン生たちはその仕事の手伝いをするというような形です。
- 会社としてはリモートワークも可能ですが、コミュニケーションが取りづらいということもあり、私は毎回オフィスに出社しています。

### インターンをして思ったこと・感じたこと
- 両立のしやすさ
うちの会社では、学校の授業との両立がしやすかったです。
自分の好きな時間に自分の好きな時間だけシフトを入れることができたり、比較的小規模な会社なので学校の定期テスト前はシフトを減らせたり、とても柔軟に対応してくれてありがたかったです。

- 悩む時間
デバッグ中に詰まったときは、数学の問題を解く時と同様にどこまで自分で悩むかの線引きが大切です。知る訳ないバックグラウンドでエラーが起きていることも時々あるので、さっぱりお手上げの時は潔くベテランの社員さんに聞くことをおすすめします。

- 世の中便利
自分が「こんなパッケージあったら便利！」と思ったものは、どうせ他の人達も「あったらいいのに〜」」と思っていて、どうせすでにパッケージ化されてるので、ネットで調べればすぐに出てくることが大半です。このような「どうせあるんでしょ？」という小賢しさは意外と重要かもしれません笑
同様にデバッグ中、謎のエラーに陥った際にも、どうせ同じようなエラーに遭遇している人が沢山いるので、ネットで調べてみるとすぐに解決法が判明したりします。

- エラー文は案外親切
エラー文をよく見ると、余程難しいものでない限りたいてい何かしらのヒントを与えてくれています。そのヒントをよく見てあげれば容易にエラー内容がわかることは多いです。ぶっきらぼうな見た目をしているようで、エラー文は案外親切なものです。是非エラー文と友達になろう！

### まとめ
私はこのインターンに参加できてとてもよかったと思っています。
なので、プログラミングに少しでも興味のある方は是非一度、私と同じように興味のある世界に飛びこんでみてはいかがでしょうか？
【Linux】中級コマンド一覧

# 初めに

前回は基本的なコマンドについて記事にしましたが今回は中級レベルのコマンドを記事にします。

# コマンド

## grep

ファイルまたは入力ストリームから、表現に一致する行を表示する。

/etc/password ファイルの中にある test というテキストを含む行を表示する。

```console
grep test /etc/password
```

## less

ファイルの内容が一度に一画面ずつ表示されます。

大量の出力するコマンドの出力を確認する場合にとても便利です。

```console
less /usr/share/dict/words
```

また、`grep`と`less`を組み合わせることをできます。

```console
grep ie /usr/share/dict/words | less
```

## pwd

カレント・ワーキング・ディレクトリの名前を出力をします。

```console
$ pwd
/Users/test
```

## diff

２つのテキストファイルの差分を知ることができます。

```console
diff file1 file2
```

## file

ファイル形式を表示します。

```console
file file
```

## find

`dir`内にある`file`を探すことができます。

```console
find dir -name file -print
```
Wikipedia(MediaWiki) APIでどうやってもCORSエラーが解決しない

どうもNuxt勉強中のnaotikiです
Nuxtで以前作った[しりとりAI](https://qiita.com/naotiki/items/b35edbf685e48ab6cecc)を作り直していたのですが、なぜか以前起きなかった問題に遭遇したのでメモとして残しておきます。
# 対象
- `Access-Control-Allow-Origin: *`とかHeaderにつけてもダメな人
- axiosとかNuxtでProxyやってもダメな人
 
# 解決策

https://stackoverflow.com/questions/23952045/wikipedia-api-cross-origin-requests

URLパラメータに`origin=*`とつけるだけ！

例.
`https://ja.wikipedia.org/w/api.php?origin=*&format=json&...`
すごいですね！
## なにこれ？
> StackOverFlow回答より
>  '&origin=*' + // <-- this is the magic ingredient!

魔法らしいです。
行数を節約するvar_dump()を書いてみた

|[../](https://qiita.com/taconana/items/3f5424f9abfc755772c2) |
|---|

var_dump()で配列をダンプすると、やたらと行数が長い。出力制御関数`ob_start()`と`ob_get_clean()`で挟み込めばテキストが取れると聞いたので、行数をほぼ1/2にするものを書いてみた。引数は1つに限定。

```php
function var_dump2($arg): void {
  ob_start(); 
  var_dump($arg); 
  $t = ob_get_clean();
  $s = '';
  while (($n = strpos($t, '=>')) > 0){
    // $s .= substr($t, 0, $n) . "=> ";
    $s .= rtrim(substr($t, 0, $n)) . " => ";
    $t = ltrim(substr($t, $n + 3));
  }
  echo $s, $t, PHP_EOL;
}
```
以下のようにpreg_replace()を使うとシンプルに書けるみたい。空白文字の処理が不完全かもしれないが。
```php
function var_dump3($arg): void {
  ob_start(); 
  var_dump($arg); 
  // echo preg_replace("/=>[\r\n\s]+/", " => ", ob_get_clean()), PHP_EOL;
  echo preg_replace("/=>[\s]+/", " => ", ob_get_clean()), PHP_EOL;
}
```
Userの配列を通常の`var_dump()`でダンプすると、以下の感じ。なお、私の環境はxdebugが入っていて、シンプルな出力形式になっていたことを知った。「[xdebugがPHP環境に入っているかどうかでvar_dump()の出力形式が変わる](https://qiita.com/taconana/items/8f4af816ad528677c332)」を参照のこと。
```
Sample.php:74:
array(2) {
  [0] =>
  class samples\User#3 (3) {
    private $mail =>
    string(11) "aaa@xxx.com"
    private $id =>
    string(4) "U001"
    private $name =>
    string(7) "Aさん"
  }
  [1] =>
  class samples\User#2 (3) {
    private $mail =>
    string(11) "bbb@xxx.com"
    private $id =>
    string(4) "U002"
    private $name =>
    string(7) "Bさん"
  }
}
```
作成した`var_dump2()`だと、以下の感じ。几帳面な日本人は、きっとこっちの方が好き。
```
Sample.php:75:
array(2) {
  [0] => class samples\User#3 (3) {
    private $mail => string(11) "aaa@xxx.com"
    private $id => string(4) "U001"
    private $name => string(7) "Aさん"
  }
  [1] => class samples\User#2 (3) {
    private $mail => string(11) "bbb@xxx.com"
    private $id => string(4) "U002"
    private $name => string(7) "Bさん"
  }
}
```

|[../](https://qiita.com/taconana/items/3f5424f9abfc755772c2) |
|---|
プログラミング初心者に役立ちそうなサイト

こんにちは。

現在、長野県のとあるA型事業所でプログラミングをしています。
通いはじめて3日ほど経ち、環境に慣れてきました。
プログラミングはほとんど未経験で、初心者状態なので、よいサイトやコンテンツを求めてネットをさまよっていました。

A型事業所としては私の担当はアプリ開発やコーディングといったジャンルが求められています。
まずは簡単なHTMLやCSSからはじめて、Javascriptの案件をこなしていくことが求められています。
コーディングの経験はほとんどなく、趣味のMML程度の技量なので、しっかり勉強していく必要を感じています。
いまのところはアプリ開発も自社事業として進めていくのでSwiftやKotlinも必要そうなのですが、まずはHTMLからはじめています。

プログラミング学習にはYouTubeが良いらしいと聞いていたので、「Javascript 初心者」などと検索をかけてでてきた動画をいくつかみてみました。
それから実際にコーディングをしながら学べるサイトを探してみました。

HTMLやCSS、Javascriptの勉強に使っているのはfreecodecampというサイトです。

freecodecamp
https://www.freecodecamp.org/japanese/learn/

以前、英語のサイトしかなかったのですが、学びやすいように翻訳されていました。
ちょっとだけやった履歴がありましたが、最初からやり直して、HTMLやCSSの復習に使いました。
これからJavascriptにはいりますが、Pythonや機械学習のコースもあるみたいなので、気になる方はみてみるといかがでしょうか？

SwiftやKotlinも求められるのでUdemyなどでコースを探したりもして、個人でSwiftのコースを買ったりはしてみたのですが、事業の内容的にはkotlinが先といった感じのようです。
kotlinに関しては英語ですが、Courseaにコースがあり、そちらを見ていました。

Kotlin for java developers
https://www.coursera.org/learn/kotlin-for-java-developers

こちらはタイトルにもあるように、すでにJavaが書ける方向けのコースのようで、初心者の私にはわかりませんでした。
実際にコーディングして課題を出さないとパスできないので将来的にやってみる感じでストックに加えておきました。
Kotlinを開発しているJetBrains社の講習なので、受けてみる価値はありそうです。

本などをAmazonで調べてみると、公式のドキュメントが良いらしいということがわかってきました。
どこにあるんだろう？と検索してみましたが、Android Developersというところにありました。

Android Developers
https://developer.android.com/?hl=ja

こちらに講座もあり、YouTubeなどでも動画が見れるようです。


英語のドキュメントなどもあり、Kotlinはだいぶ移り変わりが激しいようなので、英語にも慣れていくとよさそうと思っています。

swiftに関してはAndroidのようにAppleが用意しているコースがあるようです。そちらをまずは利用予定です。

Swift Playgrounds
https://www.apple.com/jp/swift/playgrounds/


今回は以上となります。
現状だと月曜日、金曜日に出勤していますので、またその日を目安に記事を更新したいと思います。
それでは、また。
Beansの意味と発展歴史

#### Beansとは？
+ Component（文書、モデル、テーブル、コード、ライブラリ）またはオブジェクトを意味うる。簡単に言えば、プログラミングをする際に持ち込んで再利用が可能な部品だと思えばいい

#### Beansの歴史
<strong> 1. javabean </strong>
<dd>再利用可能なComponentで、ルールは複雑。</dd>
<strong> 2. Servlet＆JSP Bean </strong>
<dd>MVCからデータを渡すModelとして機能する。ルールは簡単。JSP containerに管理される。
<br>※管理：Beanのライフサイクルを生成、消滅する行為</br></dd>
<strong> 3. EJB（Enterprise JavaBeans）</strong>
<dd>企業環境で使用するため誕生したが、ルールが複雑。 EJB containerに管理される</dd>
<strong> 4. Spring beans </strong> 
<dd>ルールがシンプルで独立的。Spring containerに管理される。
<br>現在、BeanはSpring containerが管理するオブジェクトを意味で通用されている。</br></dd>
 
:::note info
 <strong>Spring container </strong>はBeanストレージで、Beanを保存管理（生成・消滅の上、オブジェクトの関係まで管理してくれる）。→ IoCで重要な役割

 Spring containerの種類
 1. Bean Factory<dd>Beanの生成、接続などの基本機能を定義したインタフェース</dd>
 2. Application Context<dd>Bean Factory を拡張して複数の機能を追加したインターフェース。Spring containerと同義語として使用されている</dd>
:::
あぁー！チャットしてこないで！！って時の対処法

<h1>はじめに</h1>
<p>
皆さん、仕事のコミュニケーションツールは何を使っていますか？
SlackとかChatworkとか色々とありますが、やはりTeamsも多いですよね。
</p>
<p>
僕の職場ではTeamsなのですが、スマホに入れてるせいで四六時中個人チャットの通知が響きます。
<br>
困ったものなので、絶対に反応しないけど、見れるわな。というステータスにしていきます。
</p>

<h1>ステータス</h1>
Microsoft Teamsのステータスは何種類かあります。

緑・・・連絡、チャットオッケー
黄色・・・ちょっといません。トイレか居眠りです。
赤・・・取り込み中・・・
赤線・・・発表中。絶対チャットすな

...というのがメジャーなところだと思います。
「外出中」という機能を使えばこんなのを実現できます。

白抜きの緑・・・外出中だけど、連絡取れるっちゃ取れます。
赤枠の丸・・・外出中で、喋ってます
紫矢印・・・いない。絶対にいない！！！

詳しくはこちらのサイトを見てくださいな。
https://docs.microsoft.com/ja-jp/microsoftteams/presence-admins


<h1>外出中になる</h1>
見慣れないステータスになるとみんなはチャットを送らなくなります。
だからそのステータスを設定します。

1. 　自分のアイコンをクリック。
2.  「ステータスメッセージを指定」をクリック。
3. 　外出中のスケジュールをクリック。
4.  「自動応答を有効にする」をクリックしてONにする。
5.  「不在時の応答」になんの予定かーとか、不在です。とか書いておく。
6.  期間が決まってる場合、「この期間に限り応答を送信する」にチェックを入れて、開始と終了の時刻を入れる。
7.  「保存」をクリック。

<h1>外出が終わったら</h1>
 >>  4. 「自動応答を有効にする」をクリックしてONにする。<br>
このボタンをオフにして、外出中のステータスを解除することができます。

<h1>終わり</h1>
自分が忘れっぽいなと思うあなたは、期間を決めておいた方が良いです。
以外と紫矢印は強いです。
とはいっても、LINEが飛んできますが。ﾅﾊﾊ
AWS上にCentOS Stream 9 を立ち上げて、Nodejsで簡単アプリを動かしてみる

構築の際の覚書です。

## ◆AWS CentOS起動◆
CentOS8がサポート終了したとのことで、
AWS EC2 で CentOS Stream 9 のサーバーを立ち上げてみました。


### 1. 公式のCentOS 9 Ami IDを探す
公式のWiki( [https://wiki.centos.org/Cloud/AWS](https://wiki.centos.org/Cloud/AWS) )から、東京リージョン（ap-northeast-1）のAmi IDを探してコピーします。

2022/6/27時点の最新以下を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638048/900e5dbd-cf9d-a894-2ec4-d7f10737f495.png)

### 2. AWSでインスタンスを起動する
AWS EC2 「インスタンスを起動」 から、1.でコピーしたAmi IDを入力して検索します。

CentOS 8はサポート終了しているとのことで、今回CentOS Steam9を立ち上げてみることにしました。


コミュニティ AMI で1件ヒットするので、これを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638048/c2ebb3d1-866a-9cb6-245a-2b8501b0060b.png)

teratermより接続したいので、キーペア（ログイン）にて「新しいキーペアの作成」を実行し、キーペア作成します。.pem形式のファイルがダウンロードされるので、ローカルPC内の任意のフォルダに配置します。
　キーペア名：centos8_key（任意の名前）
　キーペアのタイプ：RSA
　プライベートキーファイル形式：.pem
　

他の設定は後から変更もできるのでミニマムで、デフォルト設定のままで、「インスタンスを起動」を実行して起動します。起動してきて「成功　インスタンスの起動を正常に開始しました」が確認できればOKです。
　インスタンスタイプ：t2.micro(1vCPU,1GiB)
　ネットワーク設定：（デフォルトのまま）
　ストレージ：10GiB gp2
　高度な詳細：（デフォルトのまま）


### 3. SSHにてログインする
EC2のインスタンス一覧から起動したEC2を選択し、パブリック IPv4 アドレスを確認します。

----＞なぜかsshログインできなかったです。同じ質問している方を発見！
https://teratail.com/questions/a4kz6e6h4d3gnf

結果として現状CentOS Stream 9でグローバルIPを使ったSSHログインが出来ず、CentOS8を踏み台にローカルIP経由でSSHして利用している状態で一旦使うことに。
CentOS8はすでにサポート終了してることから、yumのミラーサイトが停止しています。対処方法はありそうですが、今後も色々躓きそうなので、CentOS Steam 9を使うことにしました。


## ◆Nodejs、npm、EXPRESS、EJS、mysqlを導入◆

### 1. Nodejs、npmをyumでインストール
```
# yum list available | grep nodejs
# sudo yum install nodejs
　
※npmはnodejsインストール時に一緒にインストールされます
```

### 2. EXPRESS、EJS、mysqlをnpmでインストール

作業ディレクトリを作成します。
```
// プロジェクトディレクトリを作成
# mkdir proj
// プロジェクトディレクトリに移動
# cd proj
```
次に対話形式で、package.jsonを作成します。
package.jsonとはnpmコマンドを自作したり、インストールするモジュールをプロジェクトごとに定義することができます。
対話形式で自分の好みに合わせて設定できますが、すべてデフォルトでOK。（エンター連打）
最後まで設定が完了すると、作業ディレクトリにpackage.jsonが作成されます。
```
# npm init
```

モジュールをインストールします。
```
# npm install express
# npm install ejs
# npm install mysql
```

### 3. hello_world.jsを作成
環境構築ディレクトリにhello_world.jsを作成します。/data/proj/hello_world.jsを配置しました。

```
var express = require("express");
var app = express();

app.get("/", function (req, res) {
  res.send("Hello World");
});

app.listen(8080, () => console.log("listening on http://localhost:8080"));
```

### 4.AWSにて8080ポートを開放
デフォルト設定ではSSH 22ポートのみ開放されているため、
該当のEC2インスタンスのセキュリティグループのインバウンドルールに追加します。

↓　下記の8080ポートの行を追加　※3000ポートは別理由で立ち上げてますが不要です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638048/7977dd45-3938-7e56-af7b-c5a1a2293963.png)



### 5. プロジェクトを起動してみる
```
# node helloworld.js
```
エラーなく起動したら、https://(EC2インスタンスのグローバルIP):8080 を打鍵してみて、hello_worldと表示されることを確認できました！


### （付録）時刻同期
CentOSの時刻がUTC表示だったので、JST表示に変更しました。
```
# cd /etc
# ls -la | grep localtime
lrwxrwxrwx.  1 root root       25 Dec  4  2020 localtime -> ../usr/share/zoneinfo/UTC
# cat /etc/localtime
TZif2UTCTZif2・TC
UTC0

# rm -f /etc/localtime
# ln -s /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
# date
Mon Jun 27 11:27:34 JST 2022
```


---
参考にさせていただきました！
https://wiblok.com/js/node/express/express_setup/
https://www.t3a.jp/blog/infrastructure/set-timezone/
【競プロ】DFS全探索を書くのが苦手なあなたへ

## はじめに
こんにちは。これがQiita初投稿のkenです。
この記事を見たということはきっとあなたはDFS全探索を書くのが苦手なんだと思います。私もその気持ちわかりますよ。難しいですよね。

この記事ではPythonを使えばDFS全探索が簡単に書けることもあるよということの紹介をします。

## 本題
今回はAtcoderから[ABC233](https://atcoder.jp/contests/abc233)の[C - Product](https://atcoder.jp/contests/abc233/tasks/abc233_c)を例にとって考えていきたいと思います。
この問題では $\  \prod_{i=1}^N L_i \leq 10^5 \ $という制約がついているため、各袋$i$のなかからひとつずつボールを取り出していく全探索で答えを求めれば良さそうだということがわかります。
ここで一般的（？）に使われるのがDFSを使った全探索で以下のようなコードになります。
```python
import sys
sys.setrecursionlimit(10**7) #再帰上限数を念のため増やしておく
#入力の受け取り
N,X = map(int,input().split())
A = [list(map(int, input().split()))[1:] for _ in range(N)]

ans = 0
def dfs(i,now):
  global ans
  if i == N:
    if now == X:
      ans += 1
    return
  for a in A[i]:
    dfs(i+1,now*a)
  return
 
dfs(0,1)
print(ans)
```

これでACです。
**でもDFSってバグらせがちですよね？
再帰ってこれで合ってるのか？って不安になりますよね？
C問題でWA出したくないですよね？**

実はPythonならこの問題を再帰を使わず書くことができます。百聞は一見にしかずということで早速コードを見てもらいましょう。
```python
import math
import itertools
N,X = map(int,input().split())
A = [list(map(int, input().split()))[1:] for _ in range(N)]
ans = 0
for v in itertools.product(*A):
  if math.prod(v) == X:
    ans += 1
print(ans)
```

**どうですか？めっちゃスッキリしてますよね？**
鍵となるのは`itertools.product()`です。これは引数にリストを入れることでそれらのリストの直積を出力してくれます。引数の`*A`というのはアンパックというやつです。リストの中身を取り出して関数に渡してくれています。また、`math.prod()`というのはリストなどのイテレータの要素の積を計算する`math`モジュールの関数です。
このようにpythonのライブラリをうまくつかえばDFSを書かなくとも複雑な全探索を書くことができます。

# とはいえ
DFSから逃げてるままだといつかきっと壁にぶちあたると思うので用法・用量を守ってお使いください！！最後まで読んでいただきありがとうございました！
フローを使ってレコードの複製をつくる

ああ、バルクでなかった。

元の質問 : [レコードコレクションを別のレコードコレクションに渡すor変更する場合について](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000HnDslSAF)
2022-06-28の朝確認したら消して逃亡してましたな。かなり色々と質問に答えたのにこれだ...


[How to clone records using Flows? One flow to clone them all! #Spring20Delight](https://forcepanda.wordpress.com/2020/01/15/how-to-clone-records-using-flows-one-flow-to-clone-them-all-spring20delight/)

単発の場合はこれが使えそう。

```
public class CloneRecordFlowActionClass {
    
    @InvocableMethod(label='Clone Record')
    public static FlowOutputParameters[] cloneRecord(FlowInputParameters[] input){
        FlowOutputParameters[] result = new FlowOutputParameters[]{};
        
        sObject s = input[0].recordToClone; // 入力レコードをsObject型変数にコピーする
        s.put('Id',NULL); //レコードの「Id」フィールドをNULLとして設定する
        insert s; //Inserting the sObject record
        
        FlowOutputParameters obj = new FlowOutputParameters();
        obj.clonedRecordId = (string)s.get('Id'); //挿入されたsObjectレコードIDをコピーして、フロー出力として返します
        result.add(obj);
        
        return result;
    }
    
    /* Input parameters for the Apex action */
    public class FlowInputParameters{
        @InvocableVariable(label='Record to Clone' required = true )
        public sObject recordToClone;
    }
    
    /* Output parameters of the Apex action */
    public class FlowOutputParameters{
        @InvocableVariable(label='Cloned Record ID')
        public string clonedRecordId;
    }

}
```

複数レコードように改造

```
public class CloneRecordFlowActionClass {
    
    @InvocableMethod(label='Clone Record')
    public static FlowOutputParameters[] cloneRecord(FlowInputParameters[] input){
        FlowOutputParameters[] result = new FlowOutputParameters[]{};
        
        Integer param_count = FlowInputParameters.size();
        List<Object> insetObjList = new List<Object>();
        for (Integer i = 0, i < param_count i++) {
           sObject s = input[i].recordToClone; // 入力レコードをsObject型変数にコピーする
           s.put('Id',NULL); //レコードの「Id」フィールドをNULLとして設定する
           insetObjList.add(s);
       }    
       Database.SaveResult[] srList = Database.insert(insetObjList, false);//Inserting the sObject record
        
       
       for (Database.SaveResult sr : srList) {
          FlowOutputParameters obj = new FlowOutputParameters();
          obj.clonedRecordId = sr.getId();//挿入されたsObjectレコードIDをコピーして、フロー出力として返します
          result.add(obj);
       }        
        
       return result;
    }
    
    /* Input parameters for the Apex action */
    public class FlowInputParameters{
        @InvocableVariable(label='Record to Clone' required = true )
        public sObject recordToClone;
    }
    
    /* Output parameters of the Apex action */
    public class FlowOutputParameters{
        @InvocableVariable(label='Cloned Record ID')
        public string clonedRecordId;
    }

}
```
pythonのバージョン変更方法（aliasとpyenv）

はじめに
---
pythonを使用して構築する際に、バージョンの変更方法によって違いが発生し、詰まってしまったため、まとめておくことにしました。
AmazonLinux2を使用してpython3.9.2の適用を検証していきます。
デフォルトではpythonコマンドでは2.7.18、python3コマンドでは3.7.10が呼び出されます。

適用パターンは以下の３パターンです。
１．wgetを使用してインストール、aliasで適用
２．wgetを使用してインストール、シンボリックリンクの変更で適用
３．gitを使用してインストール、pyenvで適用

インストール方法（１，２共通）
---

### python3.9.2のインストール
インストールに必要なツールをインストールします。
```
$ sudo yum groupinstall "development tools"
$ sudo yum install gcc zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel tk-devel libffi-devel xz-devel
```
python3.9.2をインストールしていきます。
```
$ wget https://www.python.org/ftp/python/3.9.2/Python-3.9.2.tar.xz
$ tar xJf Python-3.9.2.tar.xz

$ cd Python-3.9.2
$ ./configure
$ make
$ sudo make install

$ python -V
Python 2.7.18
$ python3 -V
Python 3.9.2
```
ここまででインストールまで完了したので、pythonコマンドにも適用させていきます。

１．aliasで適用
---
aliasコマンドを使用する方法と~/.bashrcに書き込む方法の２パターンあります。
どちらもpython3がpythonコマンドになりかわっているイメージです。
```
$ alias python='python3'

$ python -V
Python 3.9.2
$ python3 -V
Python 3.9.2
```
```
$ echo "alias python='python3'" >> ~/.bashrc
$ source ~/.bashrc

$ python -V
Python 3.9.2
$ python3 -V
Python 3.9.2
```

２．シンボリックリンクの変更で適用
---
現在のパスを確認してみましょう。
```
$ which python
/usr/bin/python
$ which python3
/usr/local/bin/python3
```
このパスはそれぞれのバージョンがある場所へのシンボリックリンクになっています。
pythonコマンドのパスを適用したいバージョンへのシンボリックリンクに変更させます。
```
$ sudo rm /usr/bin/python
$ sudo ln -s /usr/local/bin/python3.9 /usr/bin/python

$ python -V
Python 3.9.2
$ python3 -V
Python 3.9.2
```

３．gitを使用してインストール、pyenvで適用
---
インストールに必要なツールをインストールします。（ここまでは１，２と共通です。）
```
$ sudo yum groupinstall "development tools"
$ sudo yum install gcc zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel tk-devel libffi-devel xz-devel　
```
~~gitから使いたいバージョンをcloneします。~~
~~gitコマンドが使用できない場合は、yumでインストールしてください。~~
下記作業は不要なので飛ばしてください。
```
$ git clone https://github.com/deadsnakes/python3.9.git
```
pyenvを使用してバージョンを切り替えるため、pyenvをインストールし、使用できるように設定していきます。
```
$ git clone https://github.com/pyenv/pyenv.git ~/.pyenv
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(pyenv init --path)"' >> ~/.bash_profile
$ echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
$ source ~/.bash_profile

$ pyenv --version
pyenv 2.3.1-20-g572a8bcf
```
pyenvのバージョンが表示されたら、使用可能です。

pyenvコマンドを使用して使いたいバージョンをインストールしていきます。
インストール可能なバージョンは`pyenv -list`で確認できます。
```
$ pyenv install 3.9.2
```
次のコマンドで切り替え可能なバージョンを確認できます。
```
$ pyenv versions
* system (set by /home/ec2-user/.pyenv/version)
  3.9.2
```
＊がついたバージョンが適用中のバージョンです。
3.9.2が使用できるように変更します。
```
$ pyenv global 3.9.2
$ pyenv versions
  system
* 3.9.2 (set by /home/ec2-user/.pyenv/version)

$ python -V
Python 3.9.2
$ python3 -V
Python 3.9.2
```

まとめ
---
pyenvはpythonのバージョン管理を行います。
複数のバージョンを切り替えながら使用するときはpyenvを使うとよいでしょう。
aliasコマンドを使用する方法は手軽ですが、インスタンスの再起動などで消える可能性があるので、注意が必要です。
個人的にはpyenvで適用していけば間違いないのかなと思いました。

参考サイト
---
[pyenvを使ってPython実行環境の構築](https://codeaid.jp/pyenv-linux/)
[AmazonLinux2でPython3環境構築](https://qiita.com/hiren/items/17984191da2ab8955174)
【PostgreSQL】【PHP】接続方法

PHPとPostgreSQL間でのデータのCRUD処理について学んだため、備忘録に残します。

PHPは元々「[PostgreSQL関数](https://www.php.net/manual/ja/ref.pgsql.php)」が用意されているため、こちらを利用することになります。

# PHPからPostgreSQLデータベースへの接続方法:2つ
1. PHPのlibpqライブラリから提供されるPostgreSQL関数を使用する方法
2. PDO(PHP Data Objects)を使用する方法

どちらの方法を使うかの判断は機能的な比較というよりも、サーバー環境やプログラマの裁量によります。
分かりやすい例としては、PDOを使って他のデータベース(MySQLやSQLiteなど)を操作するコードを記述した経験のある場合は、PostgreSQLもPDOで扱う方がスムーズかもしれません。

一方で、他のプログラミング言語(PythonやRubyなど)で関数を使っての操作コードを書いた経験がある場合は、libpqライブラリの関数を使う形で書いた方が分かりやすいはずです。

接続方法については下記記事を参考にさせていただきました。
- [PostgreSQLデータベースへ接続
](
https://gray-code.com/php/conectted-to-postgresql/#:~:text=%E3%81%A7%E6%8E%A5%E7%B6%9A%E3%81%99%E3%82%8B-,PostgreSQL%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E3%81%B8%E3%81%AE%E6%8E%A5%E7%B6%9A%E6%96%B9%E6%B3%95,%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%E3%81%A7%E3%81%99%E3%80%82)

- [PostgreSQLへ接続](https://www.javadrive.jp/php/pdo/index4.html)

今回は「PDOを使用する方法」で接続してみたいと思います。

# 接続手順

## 1. PostgreSQL インストール 〜 DB作成

こちらの記事がとても分かりやすかったので、記事の通りに進めます。
[【PostgreSQL】MacでPostgreSQLデータベースの環境をつくろう！
](https://tektektech.com/psql-mac-environment/#postgresSQL)

記事の通りに進めて、最終的にテーブルにデータを追加するところまで終わらせておきます。
私の場合は、以下のようなテーブルを作ってみました。

テーブル名：users
カラム： id, firstname, lastname
データ: 以下の通り

| id| firstname | lastname |
|:-----------|------------:|:------------:|
| 1    | Kaori       | Saito      |
| 2     | Naomi      | Tanaka       |
| 3       | Kei        | Yamada         |


![スクリーンショット 2022-06-27 12.59.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/985164/3669183c-1f26-ddc2-aef7-2384ba9fe841.png)


## 2. PHPで接続用ファイルを用意する


```php:sql.php
<?php
function convert_enc($str){
    $from_enc = 'EUC_JP';
    $to_enc = 'SJIS';

    return mb_convert_encoding($str, $to_enc, $from_enc);
}

$dsn = 'pgsql:dbname=DB名 host=localhost port=5432';
$user = 'ユーザー名';
$password = 'パスワード';

try{
    $dbh = new PDO($dsn, $user, $password);

    print('接続に成功しました。<br>');

    $sql = 'select * from users';
    foreach ($dbh->query($sql) as $row) {
        print(convert_enc($row['id']).'<br>');
        print(convert_enc($row['firstname']).'<br>');
        print(convert_enc($row['lastname']).'<br>');
    }
}catch (PDOException $e){
    print('Error:'.$e->getMessage());
    die();
}


$dbh = null;

?>
```

## 3. ビルトインサーバを立ち上げ、DBと接続されているかをブラウザで確認

```
php -S localhost:8000
```

localhost:8000/sql.phpを開くと・・・

![スクリーンショット 2022-06-27 15.16.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/985164/7062d863-6792-3088-99ff-9ce1f50a88dd.png)

接続に成功しました！
google-cloud/tasks モジュールでbodyが取得できない場合の対策

# 概要

`Cloud Tasks` に`Post`した値が取得できなかった際の対応をまとめる

https://www.npmjs.com/package/@google-cloud/tasks

# 解決方法

`Quickstart`に記載されている方法では取得できないので以下の通りにする

`body: Buffer.from(JSON.stringify(payload)).toString('base64')`

```ts
const payload = {
  foo: 'bar',
};

 const task = {
      httpRequest: {
        httpMethod: HttpMethod.POST,
        url: 'URL',
        oidcToken: {
          serviceAccountEmail:
            'serviceAccountEmail',
        },
        body: Buffer.from(JSON.stringify(payload)).toString('base64'),
        headers: {
          'Content-Type': 'application/json',
        },
      },
    }
```

https://github.com/googleapis/nodejs-tasks/issues/91#issuecomment-511240757
Command CodeSign failed with a nonzero exit codeというエラーの対処法

# 成り行き
[SwiftUIの公式チュートリアル](https://developer.apple.com/tutorials/swiftui)をやっていた所以下のようなエラーが出たので対処法を紹介します。
![ダウンロード.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2726092/6bbbe9d6-c30b-33c8-69c3-e2d7dab717ae.jpeg)

# 対処法
まず最初に、プロジェクト内に **Resourcesフォルダ** がないか確認してください。
[SwiftUIの公式チュートリアル](https://developer.apple.com/tutorials/swiftui)には **Resourcesフォルダ** を追加するところがありますがこの名前がだめらしいので、landmarkData.jsonを **Resourcesフォルダ** から出せばエラーは消えます。

# それでも消えない場合
以下のサイトを参考にして対処してください。

https://fukajima.com/2021/02/22/post-578/

https://junichisunaga.com/blog/20200223.html
Zabbix3.0から5.0へのアップグレード手順

仕事で使っているZabbix(あとphpも)を、いい加減アップグレードせんといかん、ということでZabbixのアップグレード方法をググって、検証してみた結果、以下の手順で成功したのでメモ。

# 現環境
- CenOS7
- apache2.4
- php5.6(remi)
- Zabbix3.0

※事前に下記に記載されているファイル、ディレクトリのバックアップを取っておきます。
https://www.zabbix.com/documentation/current/en/manual/installation/upgrade/packages/rhel_centos

# 1. Zabbix(サーバー側)のアップグレード

## 1-1. Zabbixサーバー(とエージェント)の停止
```
systemctl stop zabbix-server
systemctl stop zabbix-agent
```

## 1-2. php5.6をアンインストール
```
yum remove php-* \
oniguruma5php \
gd3php
```

## 1-3. remiのリポジトリを7.4に変更
```
yum-config-manager --disable remi-php56
yum-config-manager --enable remi-php74
```

## 1-4. Zabbixのリポジトリを5.0にアップデート
```
rpm -Uvh https://repo.zabbix.com/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm
yum-config-manager --enable zabbix-frontend
yum clean all
```

## 1-5. php7.4をインストール
```
yum install \
php-common \
php-xml \
php-process \
php-pecl-jsonc \
php-pdo \
php-snmp \
php-bcmath \
php-devel \
php-gd \
php-opcache \
php-cli \
php-mbstring \
php-pecl-zip \
php \
php-mysqlnd \
php-mcrypt \
php-fedora-autoloader \
php-pear \
php-ldap \
php-imap
```

## 1-6. apacheのconfigを変更
```vi /etc/httpd/conf.d/zabbix.conf
-<IfModule mod_php5.c>
+<IfModule mod_php7.c>
```

## 1-7. Zabbix5.0へアップグレード
```
yum upgrade zabbix-server-mysql zabbix-agent
yum install zabbix-web zabbix-web-japanese
```

## 1-8. DBをダンプしてCHARSET(COLLATEを追加)を修正
```
mysqldump -u zabbix -p zabbix > zabbix_db.sql
sed "s/CHARSET=utf8/CHARSET=utf8 COLLATE=utf8_bin/" zabbix_db.sql > zabbix_db_conv.sql
```

## 1-9. DBを再作成してインポート(DROP>CREATEはお好みで)
```
mysql -u root -p
> drop database zabbix;
> CREATE DATABASE zabbix character set utf8 collate utf8_bin;
> grant all privileges on zabbix.* to zabbix@localhost identified by '**********';

mysql -u zabbix -p zabbix < zabbix_db_conv.sql
```

## 1-10. カラムの型を変更
```
wget https://git.zabbix.com/projects/ZBX/repos/zabbix/raw/database/mysql/double.sql
mysql -u zabbix -p zabbix < double.sql
```

## 1-11. zabbix_server.confを5.0用に変更
```
cp /etc/zabbix/zabbix_server.conf.rpmnew /etc/zabbix/zabbix_server.conf
 
vi /etc/zabbix/zabbix_server.conf
-----
DBPassword=**********
-----
```

## 1-12. Zabbixサーバー(とエージェント)の起動
```
systemctl start zabbix-server
systemctl start zabbix-agent
```

# 2. Zabbix(クライアント側)のアップグレード

## 2-1. Zabbixエージェントの停止
```
systemctl stop zabbix-agent
```

## 2-2. Zabbixのリポジトリを5.0にアップデート
```
rpm -Uvh https://repo.zabbix.com/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm
yum clean all
yum upgrade zabbix-agent
```

## 2-3. zabbix_agentd.confの設定
```
cp /etc/zabbix/zabbix_agentd.conf.rpmnew /etc/zabbix/zabbix_agentd.conf

vi /etc/zabbix/zabbix_agentd.conf
-----
Server=ZabbixサーバーのIP(ホスト名)
ServerActive=ZabbixサーバーのIP(ホスト名)
Hostname=クライアントのホスト名
HostnameItem=system.hostname
HostMetadata=Linux ********
AllowRoot=1
-----
```

## 2-4. エージェントのログを削除(若しくはオーナーをzabbixに変更)
```
rm -f /var/log/zabbix/zabbix_agentd.log 
```

## 2-5. Zabbixエージェントの起動
```
systemctl start zabbix-agent
```
プログラミング未経験者が育休中にKagglerになるまでの記録

プログラミング未経験30代サラリーウーマンです。
現在の仕事はプログラミングが無くともやっていける業種ですが、
育休という期間を利用してプログラミング（Python）を習得し、
あわよくばkagglerになりたいと思っております。


1年弱の期間、どの程度まで成長できるか、こちらで記録してまいります。


# プログラミングを習得するモチベーション
・仕事に付加価値をつけたい。
・次世代と対等なスキルを身につけたい。
・副業や転職したい。


# kagglerになるモチベーション
・かっこいいから。


# やったこと（ 2021/12 ~ 2022/6 現在）
１．ProgateでPythonの基本を確認。
２．Google ColaboratoryでPythonコードを書いてみる。
３．Pythonノック動画を観てコードを書き復習。
４．UdemyのKaggle講座を受けてみる（修了）。
５．Twitterアカウントを作成しプログラマー情報を見てみる。
６．G検定を受けてみる（合格）。
７．KaggleのCoursesをノートに書き写し理解。
８．Signateの初学者向け練習問題コンペを解いてみる。
９．Qiitaのアカウントを作り記事を見てみる。


# やってみた感想
・kaggleのCoursesがプログラミングや機械学習の基礎を端的に説明しており、
　とにかくわかりやすい。
・コンペ問題を解きながらコードを覚える方法が自分に合ってる（おもしろい）。
・統計検定2級を受けるつもりだったが、切り捨てた。
　勿論やった方が良いが、学習速度が著しく低下（おもしろくなかった）ので、
　まずは手を動かすことにシフト。元気が出たらまたやるかも。


# 現在の腕前
・kaggleの他者のコードで何をしているのかなんとなくわかる。
・コードの意味がわからなくても挫折せずコピペして調べられる。
・Python基礎やったが正直暗記してないから毎度調べる。
・G検定に出てきたDeep learningのテクニックはなんとなくわかった気に。
・英語を読むのが苦じゃなくなった。但し、ほぼDeepLに頼ってる。
・実務に応用するにはまだまだまだまだな実力。


# 次の1か月の目標
・kaggleコンペ、Signateコンペに参加。
・特徴量エンジニアリングの引き出しを増やす。







引き続き、がんばります！
AWS Certified Database - Specialty(DBS-C01) を取得しました

# はじめに
AWS認定コンプリートを目指すべく、DBS-C01を取得しました。

# AWS Certified Database - Specialty(DBS-C01) とは
[この辺](https://aws.amazon.com/jp/certification/certified-database-specialty/)を参照ください。

# 教材
下記を約2週間かけて取り組みました。

1. Udemy：[AWS Certified Database - Specialty 模擬試験](https://www.udemy.com/course/aws-certified-database-specialty-japanese/)
    - 日本語問題集です。
    - 問題数は少なく65問です。
1. Udemy：[Practice Exam | AWS Certified Database Specialty](https://www.udemy.com/course/practice-exams-aws-certified-database-specialty/)
    - 英語問題集です。講義版もあるようですが、そちらは購入していません。
    - 問題数は少なく65問です。上記と若干内容が重複している箇所があります。
1. [WEB問題集で学習しよう](https://aws.koiwaclub.com/exam/dbs/)
    - おなじみのやつです。
    - 119問(17セクションx7問)です。
    - 上記と内容が重複しますが、正答が違ったりします。内容を見極める必要があります。
1. [試験問題サンプル](https://d1.awsstatic.com/ja_JP/training-and-certification/docs-database-specialty/AWS-Certified-Database-Specialty_Sample-Questions.pdf)
    - 公式の試験問題サンプルです。
1. [Exam Readiness: AWS Certified Database - Specialty (Japanese)](https://explore.skillbuilder.aws/learn/course/51/exam-readiness-aws-certified-data-analytics-specialty)
    - 公式の講義+問題集です。
1. [AWS Certified Database - Specialty Official Practice Question Set (DBS - Japanese)](https://amazonwebservices.benchprep.com/app/aws-certification-official-practice-question-sets-japanese#exams/details/119941)
    - 公式の模擬試験です。
    - [こちら](https://explore.skillbuilder.aws/learn/course/12511/aws-certified-database-specialty-official-practice-question-set-dbs-c01-japanese)へ移行しており6/30には停止すると案内されますが、新しい方を登録していざ始めようとするとエラーとなり利用できません。。。

# 結果
他の方の受験記を見ると割と簡単そうに思えたため、軽い気持ちで受けましたが、結構苦戦しました。上記と似たような問題は2割、似てはいないが即答できたのは2割、残り6割は悩むような内容でした。上記問題集に対して、さらにもう一段階難しくしたような感じでした。
60分で一周し、30分で見直しをしています。
苦戦したのは、RDS for SQL Server,DocumentDB,Neptune,ElastiCache,DMSあたりで、設定系の突っ込んだ内容であり、消去法＋感で回答しています。

# 感想
- 何はともあれ受かってよかったです。次は、MLSを受ける予定です。
PHP7.4で、OPcacheをインストールしてみる

|[../](https://qiita.com/taconana/items/d382d08a83a2a67f3b6a) |
|---|

OPcacheは、PHPの処理を高速にするため、コンパイル済みのバイトコードをキャッシュする。PHPのコードの解析・解釈をスキップすることができ、高速化が図れる。

OPcacheは、標準でインストールされているようだ。

```bash
$ dnf list php-opcache
php-opcache.x86_64  7.4.19-2.module_el8.6.0+1075+ab70be85  @appstream

$ vi /etc/php.d/10-opcache.ini

opcache.enable=1
opcache.enable_cli=1
opcache.memory_consumption=128
opcache.max_accelerated_files=4000

$ systemctl restart nginx
```
OPcacheは、標準でインストールされ、既に有効化されていた。既に機能してくれていたんだ！

|[../](https://qiita.com/taconana/items/d382d08a83a2a67f3b6a) |
|---|
Next.js: Redux Toolkit の使い方 (Typescript)

こちらを参考にしました。
[next.js + typescript で Redux Toolkit を使う最小サンプル](https://zenn.dev/matsutoba/articles/a9695787d616bf)
[Next.js + Redux Toolkit](https://teratail.com/questions/a91qdzycbf52hj)

プロジェクトの作成

```bash
npx create-next-app ex01 --ts
cd ex01
yarn add @reduxjs/toolkit react-redux
yarn dev
```

## プログラム ##

```tsx:pages/index.tsx
// ---------------------------------------------------------------
//	index.tsx
//
// ---------------------------------------------------------------
import { useDispatch, useSelector } from "react-redux";
import { counterSlice, CounterState, store } from "./_app";
import { NextPage } from "next";

// ---------------------------------------------------------------
const Home: NextPage = () => {
  const dispatch = useDispatch();
  const selector = useSelector((state: CounterState) => state);
  const { increment, decrement } = counterSlice.actions;

  return (
    <div>
<p>Hello World!</p>
      <p>{store.getState().counter.value}</p>
      <button onClick={() => { dispatch(increment()); }} > Plus </button>
	&nbsp;&nbsp;
      <button onClick={() => { dispatch(decrement()); }} > Minus </button>
	<p>Jun/27/2022 PM 14:55</p>
    </div>
  );
};

export default Home;

// ---------------------------------------------------------------
```

```tsx:pages/_app.tsx
// ---------------------------------------------------------------
//	_app.tsx
//
// ---------------------------------------------------------------

import React from "react";
import type { AppProps } from "next/app";
import { Provider } from "react-redux";
import { configureStore, createSlice } from "@reduxjs/toolkit";

// ---------------------------------------------------------------
export type CounterState = {
  value: number;
};

// ---------------------------------------------------------------
const initialState: CounterState = { value: 0 };

// ---------------------------------------------------------------
export const counterSlice = createSlice({
  name: "counter",
  initialState,
  reducers: {
    increment(state) {
      state.value++;
    },
    decrement(state) {
      state.value--;
    },
  },
});

// ---------------------------------------------------------------
export const store = configureStore({
  reducer: {
    counter: counterSlice.reducer,
  },
});

// ---------------------------------------------------------------
function MyApp({ Component, pageProps }: AppProps) {
  return (
    <Provider store={store}>
      <Component {...pageProps} />
    </Provider>
  );
}

export default MyApp;
// ---------------------------------------------------------------
```

ブラウザーで、　http://localhost:3000/　にアクセス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/6d861205-90a7-e35e-94d2-2be67e937bb3.png)
【Flutter】画像を使ったダイアログの表示

# はじめに
Flutterで、よくアプリを最初に開いた時に出る、通知をオンにしてください！みたいな、画像を使ったダイアログを表示したいと思い調べてみたんですが、日本語の記事を見つけられなかったので記事にします。

# 例
```dart:dialog.dart
void _openDialog() {
    return showDialog(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          titlePadding: EdgeInsets.zero, //titleの周りについているpaddingを無しにする
          title : Image.network(
          '画像のパス',
            height: 200,  //写真の高さ指定
            fit: BoxFit.cover,  //写真が周りに目一杯広がるようにする
          ),
          content: Text("テキストテキスト"),
          actions: <Widget>[
            TextButton(
              child: Text('OK'),
              onPressed: () {
                Navigator.of(context).pop();
              },
            ),
          ],
        );
      },
    );
  }
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2567243/7e28811c-daf2-9b35-4ffa-04a55f6650cf.png" width="388" height="780">

上記のコードだと、こんな感じになります！
上の書き方を使えばtitleでもcontentでも画像を使ったダイアログができますので、参考にしていただけたら幸いです！

お疲れ様でした！
Python3.7以上の環境でpyaudioをインストールする


<!-- 1 Intro -------------------------------------------->

# Introdaction

1. Python3.7以上でリアルタイム音声認識プログラムを構築する際に、pyaudioが必要になった。
1. `pip3 install pyaudio`ではインストールに失敗した。
    - fatal error: 'portaudio.h' file not found
    - brewでportaudioをインストールしていても、見つけられないとエラーが吐かれる状況
1. python3.7以上の環境でpyaudioをインストールする方法をまとめる
    - 多くの情報が既に公開されているが、自分用のまとめとして本記事を作成する


## 環境

- Apple silicon Mac
    - macOS Monterey
- Windows 10 
- Python3.7以上

## Install for Mac

以下のコマンドで外部のヘッダファイル、ライブラリのディレクトリを指定してインストールすればよい[[ref. 1](#references)]。

apple siliconの場合はhomebrewのインストール先が変更されていることに留意されたし。Apple siliconの場合とIntel cpuの環境の場合とで、適宜pathを変更する。


```terminal:apple silicon (arm64) の場合
pip3 install --global-option='build_ext' --global-option='-I/opt/homebrew/Cellar/portaudio/19.7.0/include' --global-option='-L/opt/homebrew/Cellar/portaudio/19.7.0/lib' pyaudio
```

```terminal: intel cpu (x86_64)の場合
pip3 install --global-option='build_ext' --global-option='-I/usr/local/Cellar/portaudio/19.7.0/include' --global-option='-L/usr/local/Cellar/portaudio/19.7.0/lib' pyaudio
```

`pip3 list`で`PyAudio`がインストールされていることが確認できればok。

## Install for Windows

Windows環境の場合は、非公式ではあるがビルド済みのパッケージを公開されているので[[ref. 2](#references)]、そちらを使ってインストールするのが一番楽である。細かい方法はこちらのページ「Pythonで音声録音・再生ができるPyAudioのインストール」[[ref. 3](#references)]を参照されたし。

1. 自分のPythonとOSアーキテクチャ環境にあったパッケージを自分の開発環境にダウンロードする
1. 開発環境下でパッケージをインストールする

例えばpython3.9、64bit版OSの場合は、`PyAudio‑0.2.11‑cp39‑cp39‑win_amd64.whl`をダウンロードし、以下のコマンドを実行すればよい。

```
pip install PyAudio‑0.2.11‑cp39‑cp39‑win_amd64.whl
```


## Python3.6環境で良い場合

もともとpyaudioの公式サポートがpython3.6までであることが原因にあるとのこと。インストール方法の詳細は省くが、macでもwindowsでもpython3.6環境を用意すれば苦労せずにpyaudioはインストールできる。python3.6環境で良い人はこれで良い。matlabから呼び出したいなどの場合は、matlabがpython3.6に対応していないためにpython３.7以上で用意する必要がある。




----

<!-- 5 Ref ---------------------------------------------------->
# References

1. [M1mac Pyaudioインストール時エラー対応Python - Qiita](https://qiita.com/m_ina/items/a2c37cf9457bd21c76b6)
1. [Archived: Unofficial Windows Binaries for Python Extension Packages](https://www.lfd.uci.edu/~gohlke/pythonlibs/#pyaudio)
1. [Pythonで音声録音・再生ができるPyAudioのインストール](https://self-development.info/pythonで音声録音・再生ができるpyaudioのインストール/)
[JavaScript]filter()で連想配列を指定条件で絞り込む

# はじめに
今回は、JavaScriptのfilter()について学んだことをまとめておきたいと思います。

filter()の基本構文の説明後、タイトルのサンプルコードを紹介します。

# 目次
[1.filterメソッドとは](#1-filterメソッドとは)
[2.本題](#2-本題)
[3.参考記事](#3-参考記事)

# 1. filterメソッドとは

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

filter()は、配列の要素を絞り込み、処理結果を新しい配列として返すメソッドです。
基本構文は以下のようになっています。

## 基本構文
```js
配列データ.filter(( value, index, array ) => {
   // 絞り込むための条件を記載
})
```
コールバック関数の中では絞込みたい条件を記載し、**true** を返した場合のみ新しい配列に追加します。

コールバック関数の引数には
- 第１引数：現在処理されている要素の値
- 第２引数：現在処理されている要素の配列内におけるインデックス（**省略可**）
- 第３引数：現在処理している配列（**省略可**）

の３つを渡すことができます。

## サンプルコード
```js
const nums = [12, 71, 43, 38, 50];
const filteredNums = nums.filter(function(value){
  return value > 40;
});

console.log(filteredNums);
// [71, 43, 50]

console.log(nums);
// [12, 71, 43, 38, 50]
```

上記の結果から、元の配列には手を加えずに、新しい配列が返り値となっていることが分かります。

# 2. 本題
`hobby`が`game`であるという条件で絞り込みを行いました。

### filterメソッドで連想配列を指定条件で絞り込む
```js
const users = [
  {'id': 1, 'hobby': 'game'},
  {'id': 2, 'hobby': 'game'},
  {'id': 3, 'hobby': 'camp'},
  {'id': 4, 'hobby': 'climbing'},
  {'id': 5, 'hobby': 'game'}
]
const filteredusers = users.filter(user => user.hobby === 'game')
console.log(filteredusers)
/*
[
  {'id': 1, 'hobby': 'game'},
  {'id': 2, 'hobby': 'game'},
  {'id': 5, 'hobby': 'game'}
]
*/
```
以上で実装完了です。

シンプルに書くことができるので、新しい配列を作成する際などにうまく活用していきたいと思います。

# 3. 参考文献

https://www.fenet.jp/dotnet/column/language/7232/
Liberty と Keycloak で SAML認証

# 目的
SAML認証の構成は難しいので、Dockerとスクリプトで自動で構成できるようにします。
# Gitレポジトリ
用意したGitレポジトリをクローンします。

```
git clone https://github.com/pdprof/security-auth.git
cd security-auth/saml-docker
```

# Dockerイメージのビルド
LibertyとKeycloakのイメージをビルドします。まず、ブラウザでアクセスするホスト名を環境変数 ACCESS_HOST に指定します。ローカルでテストしている場合はlocalhost、リモートの場合はそのホスト名を指定します。

- 認証で使用するのでアクセス時のホストに一致させる必要があります。
- setup-docker.sh で docker の liberty(ol) と keycloak(kc) が開始します。
- Keycloakのビルドと起動後に100秒の待ち時間があります。環境によってはこの時間を延ばしてください。

```
export ACCESS_HOST=localhost
./setup-docker.sh
```

# SAML認証の動作確認

http://localhost:9080/security.auth/

にアクセスします。Keycloakの認証画面が表示されたら

```
Username: pdprof
Password: password
```

を入力して Sign In します。httpsの証明書エラーが表示されますが、問題ないものとしてアクセスを継続します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262366/b8afe70f-b449-68c3-69e1-28e0744f8ad9.png)

が表示されれば成功です。


# ブラウザでの Keycloak 構成確認

自動で構成されてしまう keycloak の構成を確認します。

http://localhost:8080/auth/admin/master/console/#/realms/pdprof/clients

にアクセスします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262366/71ad5f8f-c868-d6c7-ad86-ec14d9a54dd4.png)

```
admin
password
```

で Sign In します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262366/52ca2cdf-fe07-d846-fb58-4bbb47f2632e.png)


次の画面では変更する必要はありません。左側 の Clients をクリックして　Client ID に

```
https://localhost:9443/ibm/saml20/defaultSP 
```
があることを確認します。

自動ではなく手動で構成する場合の手順です。テーブル右上の Create ボタンを押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262366/ff7534f7-c33b-f638-a9be-65bdecd32c85.png)

- Client Protocol に saml を選択
- Select file ボタンで　setup-docker.sh を実行したディレクトリに spMetadata.xml があるので選択
- Save ボタンを押す

# まとめ

LibertyでSAMLの構成を自動でできることを確認しました。作成された libertyの server.xml を、環境にあわせて構成を調整して応用しましょう。
LINE WORKS API 2.0 を PowerShell で叩いてみる (その6 : ユーザーの変更、部分変更)

[前回]は、LINE WORKS API を利用してユーザーを作成しました。
今回は、ユーザーの変更と部分変更を試してみます。

変更(PUT)と部分変更(PATCH)の違いですが、変更(PUT)は、プロパティ一式を含むリクエストを送り、そのとおりの内容でそっくりそのまま置き換えます。部分更新(PATCH)は、更新したいプロパティのみを含むリクエストを送り、そのプロパティだけを書き換えることができます。
早速使い方を見てみましょう。

まずは、[ユーザーの更新](https://developers.worksmobile.com/jp/reference/user-update-put?lang=ja)から。
ユーザーの登録時には `telephone` を指定していましたが、実は、固定電話ではなく、携帯電話の番号だったようです。これは修正の必要がありますね。`telephone` には値を指定せず、`cellPhone` のみを指定して更新しましょう。
`passwordConfig` はユーザー作成時にのみ設定できるので、今回は指定しません。`domainId` と `email`、`userName` のうち `lastName` と `firstName` のどちらか一方は、ユーザーの更新時にも必ず指定が必要です。 

```powershell

$userId = 'newuser@yourcompany'
$urlEncodedUserId =  [System.Web.HttpUtility]::UrlEncode($userId)

$putUserURL = "https://www.worksapis.com/v1.0/users/$urlEncodedUserId"

[HashTable]$User = @{
    domainId        = 12345678
    email           = "newuser@yourcompany"
    userName        = @{
        lastName            = "lastName"
    }
    cellPhone       = "090-1234-5678"
}

$response = Invoke-RestMethod -Method PUT -Uri $putUserURL -Headers $Header -body (ConvertTo-Json  $User -depth 10)

```

レスポンスから、`cellPhone` と `telephone` を確認してみましょう。
更新時に指定した `cellPhone` のみ値が入っていて、`telephone` からは値がなくなっていることがわかります。

```
> $response.cellPhone
0９0-1234-5678
> $response.telephone
```


では、次に、[ユーザーの部分更新](https://developers.worksmobile.com/jp/reference/user-update-patch?lang=ja)を試してみましょう。
今度は、`nickName` を指定してみます。
日本語が含まれていると、文字化けを起こしたり、不正な文字が含まれてエラーとなる場合があります。そんなときは、UTF8 でエンコードしてから送ります。

```powershell
$userId = 'newuser@yourcompany'
$urlEncodedUserId =  [System.Web.HttpUtility]::UrlEncode($userId)

$patchUserURL = "https://www.worksapis.com/v1.0/users/$urlEncodedUserId"

[HashTable]$User = @{
    nickName = "宴会部長"
}
$reqBody = $User | ConvertTo-Json -depth 10
$reqBody = [System.Text.Encoding]::UTF8.GetBytes($reqBody)

$response = Invoke-RestMethod -Method patch -Uri $patchUserURL -Headers $Header -body $reqBody
```

これで、`nickName` が正しく入りました。
```
> $response.nickName
宴会部長     
```

以前に指定した `cellPhone` も失われず、そのまま残っています。部分更新(PATCH)では指定部分だけが置き換わる事がわかります。
```
> $response.cellPhone
0９0-1234-5678     
```

一部の情報だけを消したいときもありますよね。そんな場合には、値に `$NULL` を指定して、部分更新をします。

```powershell
$userId = 'newuser@yourcompany'
$urlEncodedUserId =  [System.Web.HttpUtility]::UrlEncode($userId)

$patchUserURL = "https://www.worksapis.com/v1.0/users/$urlEncodedUserId"

[HashTable]$User = @{
    nickName = $null
}
$reqBody = $User | ConvertTo-Json -depth 10
$reqBody = [System.Text.Encoding]::UTF8.GetBytes($reqBody)

$response = Invoke-RestMethod -Method patch -Uri $patchUserURL -Headers $Header -body $reqBody
```

これで、`nickName` の情報が消えました。
```
> $response.nickName
```




このように、一部の情報だけを書き換えたいときには部分更新(PATCH)、新しい情報をすべて記載する場合には更新（PUT） と使い分けてみてください。
WordPressでの「gd がインストールされていないか、無効化されています」の対応


|[../](https://qiita.com/taconana/items/d382d08a83a2a67f3b6a) |
|---|

WordPressのダッシュボードを見ると、サイトヘルスにいくつかエラーやワーニングが出ていたので対応した。特に「必須モジュール gd がインストールされていないか、無効化されています」は、致命的なエラーになっていた。
 
## 必須モジュール gd がインストールされていないか、無効化されています!

これは、php-gdをインストールすれば解決した。
```
$ dnf install php-gd

$ vi /etc/php.d/20-gd.ini
; Enable gd extension module
extension=gd

$ systemctl restart nginx
```

## オプションのモジュール imagick がインストールされていないか、無効化されています!

これはWarningのようだ。ImageMagickのインストールはちょっと面倒。gccとmakeを入れてコンパイルしないといけない。作成されたimagick.soは /usr/lib64/php/modules に配置される。
```
$ dnf install --enablerepo=epel,powertools ImageMagick ImageMagick-devel
$ dnf install --enablerepo=epel php-devel php-pear make
$ pecl install imagick

$ echo "extension=imagick.so" > /etc/php.d/20-imagick.ini
$ vi /etc/php.d/20-imagick.ini
extension=imagick.so

$ cd /usr/lib64/php/modules
$ chmod 755 imagick.so
$ ls -lag imagick.so
-rwxr-xr-x 1 root root 1646872 2022-06-27 12:27 imagick.so

$ systemctl restart nginx
```

## オプションのモジュール zip がインストールされていないか、無効化されています。

これもWarningだ。php-zipをインストールして解決した。
```
$ dnf install php-zip

$ vi /etc/php.d/40-zip.ini
; Enable ZIP extension module
extension=zip.so

$ systemctl restart nginx
```

## オプションのモジュール intl がインストールされていないか、無効化されています。

これもWarningだ。php-intlをインストールして解決した。
```
$ dnf install php-intl
$ vi /etc/php.d/20-intl.ini
; Enable intl extension module
extension=intl

$ systemctl restart nginx
```

## REST API の呼び出しは、以下の予期しない結果でした: (404)

このWarningは、ネット情報をみて対応した。パーマリンク設定がデフォルトのままだと、WP REST APIが動かないそうだ。デフォルト設定のものから他のものを選択しなおせば、解決するらしい。「設定 -> パーマリンク」を開いて、ラジオボタンで選ばれていないものを選び直した。

「すばらしい ! すべて問題なく動作中です」と出ると、気持ちいい。

|[../](https://qiita.com/taconana/items/d382d08a83a2a67f3b6a) |
|---|