OmniAICreator/Qiita-1.07M huggingface dataset:
[React] Reactの学習をします（2-3）React Router を用いた複数ページ Web アプリの開発

#Reactの学習をします（2-3）

引き続き、Reactの学習をしています。

前回の記事　：　[[React] Reactの学習をします（2-2）Node.js による API サーバー開発](https://qiita.com/IwashiMorino/items/388614214c56fcb45f68 "[React] Reactの学習をします（2-2）Node.js による API サーバー開発")

##教材

[Reactチュートリアル2：レビューサイトを作ろう](https://zenn.dev/likr/articles/react-with-heroku#react-router-%E3%82%92%E7%94%A8%E3%81%84%E3%81%9F%E8%A4%87%E6%95%B0%E3%83%9A%E3%83%BC%E3%82%B8-web-%E3%82%A2%E3%83%97%E3%83%AA%E3%81%AE%E9%96%8B%E7%99%BA "Reactチュートリアル2：レビューサイトを作ろう")

引き続き、likr さんが公開している「Reactチュートリアル2：レビューサイトを作ろう」という記事を教材に学習させて頂きます。

素晴らしい教材をありがとうございます。

##成果物

このチュートリアル2につきましては、チュートリアルの通りに作成し既にNetlifyに公開させて頂いております。

こちらです　→　[日大文理ラーメンレビュー](https://friendly-hopper-e0a9d5.netlify.app/ "日大文理ラーメンレビュー")

##学習日記

既に作成済ですが、少しずつチュートリアルの内容を読み返してみたいと思います。

※ 教材から箇条書き的に抜粋させて頂きます。

##React Router を用いた複数ページ Web アプリの開発

>・React で複数ページから構成される Web アプリを開発するためには React Router を使用します。

client/src/App.js をチュートリアルの内容で作成します。

>・ここでは、react-router-dom からインポートした Router と Switch 、 Router という 3 つのコンポーネントが登場します。

>・**_Router コンポーネント_**は、React Router が管理するコンポーネントの範囲を設定します。
>・基本的にはアプリケーションのコンポーネント全体を Router コンポーネントの子要素にしておくとよいでしょう。

>・**_Switch コンポーネント_**は、URL によって切り替わる要素の場所を設定します。

>・**_Route コンポーネント_**は、path 属性を持ち、URL が path と一致したときにページに表示させる内容を設定します。

##フロントエンドからの API リクエスト

1.環境変数の利用

>・開発環境と本番環境（最終的に公開する環境）でパラメータを切り替える必要がある場合には環境変数を利用すると良いでしょう。
>・react-scripts を使っていれば、開発環境用の環境変数を **.env.development** 、本番環境用の環境変数を **.env.production** で設定することができます。
>・これらのファイルには REACT_APP_ から始まる環境変数名を記述します。

2.API サーバーのエンドポイントに対応した関数の作成

>・**/restaurants** と **/restaurants/:restaurantId** 、 **/restaurants/:restaurantId/reviews** に対して GET リクエストを行う関数をそれぞれ **getRestaurants** 、 **getRestaurant** 、**getRestaurantReviews** としています。

>これらの間の共通の処理は request 関数にまとめています。

3.CORS の設定を追加

>・フロントエンドと異なるオリジンとの通信は **CORS（Cross-Origin Resource Sharing）** と呼ばれます。


（つづく）
sudoコマンドでパスワードを聞かれないようにする

## 手順

1. `visudo`コマンドで設定ファイル(`/etc/sudoers`ファイル)を編集する。

    ```shell
    sudo visudo /etc/sudoers
    ```

1. ユーザを指定する場合、次のように記述する。

    ```shell
    sshuser ALL=(ALL) NOPASSWD:ALL
    ```

1. グループを指定する場合、次のように記述する。

    ```shell
    %wheel ALL=(ALL) NOPASSWD:ALL
    ```

1. ファイルを保存し、`visudo`コマンドを終了する。
【Vue.js】v-bindの記法について


v-bindにより、Vueインスタンスから、htmlに属性をセットすることができる。

```html

<div id="app">
  <a v-bind:href="url">リンク</a>
</div>

<script>
  new Vue({
  el: '#app',
  data: {
    url: 'https://google.com'
  }
})
</script>
```

生成されるHTML

```html
<div id="app">
  <a href="https://google.com">リンク</a>
</div>
```
v-bindは省略して記述できる。(:のみでオッケー）

```html
<div id="app">
  <a :href="url">リンク</a>
</div>
```

属性を動的に指定する。（[]で指定する）

```html
<div id="app">
  <a :[attr]="url">リンク</a>
</div>

<script>
new Vue({
  el: '#app',
  data: {
    url: 'https://google.com',
    attr:'href'
  }
})
</script>
```
属性をオブジェクトで設定する。

```html
<div id="app">
  <a v-bind="attrs">リンク</a>
</div>

<script>
  new Vue({
  el: '#app',
  data: {
    attrs:{
      href:'https://google.com',
      id: 10
    }
  }
})
```

生成されるhtml

```html

<div id="app">
  <a href="https://google.com" id="10">リンク</a>
</div>
```
WPFでMahAppsとMaterialDesignを使用しているとDark, Lightモードで表示がうまくいかなくなる

#はじめに
以前[MahAppsでカラー設定の保存と利用](https://qiita.com/mkuwan/items/e4a27831dde48c5cd946)という記事を書きましたが、そこでテーマをDarkモードにした場合、文字が白抜きになるのはずなのですが、コントロールによって黒文字のままだったり、白背景に白文字という現象が起きました。

#問題
本当はこう(Dark)なのに
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/956246/306d5330-e1ec-353c-1aba-78b10f24f348.png)
それがこうなる(一番左のListBoxが黒文字)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/956246/b89fdf07-8806-8410-f259-1c0e22897488.png)

Lightの場合本当はこうなるはず
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/956246/93f21d1a-547b-b818-e225-21ed831cff39.png)
それがこうなる(罫線が見えない(白い？))
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/956246/64af4532-2fce-5f85-1553-29face7bc68f.png)

#解決
以前の記事でSetThemeAndColorを呼び出していましたが、その前に以下のようにApplyBaseThemeを呼び出して設定するとうまくいきました。


```C#
using MaterialDesignThemes.Wpf;

private readonly PaletteHelper _paletteHelper = new PaletteHelper();

public void ApplyBaseTheme(bool isDark)
{
    ITheme theme = _paletteHelper.GetTheme();
    IBaseTheme baseTheme = isDark ? new MaterialDesignDarkTheme() : (IBaseTheme)new MaterialDesignLightTheme();
    theme.SetBaseTheme(baseTheme);
    _paletteHelper.SetTheme(theme);
}
```
MaterialDesign側のテーマ設定を先に行って、それから通常のテーマ設定をするとうまくカラーが設定できるようです。
こんな感じです

```C#
    private void ApplyBase(bool isDark)
    {
        // ApplyBaseThemeを行う
        _materialDesignColorService.ApplyBaseTheme(isDark);

        // SetThemeAndColorを行う
        OnSetTheme(isDark);

        // カラーを保存
        _materialDesignColorService.SaveMaterialDesignColors();
    }

    private void OnSetTheme(bool isDark)
    {
        AppTheme apptheme; //AppTheme:enum Dark, Light
        if (isDark)
        {
            apptheme = (AppTheme)Enum.Parse(typeof(AppTheme), "Dark");
        }
        else
        {
            apptheme = (AppTheme)Enum.Parse(typeof(AppTheme), "Light");
        }

        _themeSelectorService.SetThemeAndColor(apptheme, SelectedWindowColor.Value);
    }
```
Ruby on Rails アプリにVuetifyとFontAwesomeの導入

# Vuetify導入

``` 
yarn add vuetify @fortawesome/fontawesome-free
```

```javascript:app/javascript/packs/plugins/vuetify.js
import Vue from 'vue'
import Vuetify from 'vuetify'
import "vuetify/dist/vuetify.min.css"
import '@fortawesome/fontawesome-free/css/all.css'

Vue.use(Vuetify)
export default new Vuetify({
  icons: {
    iconfont: 'fa',
  }
})
```


```javascript:app/javascript/packs/main.js
import vuetify from './plugins/vuetify'

document.addEventListener('DOMContentLoaded', () => {
  const app = new Vue({
    vuetify,
    render: h => h(App)
  }).$mount()
  document.body.appendChild(app.$el)
})
```

### 使用例

```html 
<v-icon>fas fa-home</v-icon>
```


# FontAwesome導入

```
yarn add @fortawesome/fontawesome-svg-core @fortawesome/vue-fontawesome
```

```javascript:app/javascript/packs/main.js
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
Vue.config.productionTip = false
Vue.component('FontAwesomeIcon', FontAwesomeIcon)
```

### 使用例

```html
<FontAwesomeIcon icon="user"/>
<FontAwesomeIcon :icon="['far', 'star']"/>
<FontAwesomeIcon :icon="['fab', 'facebook']"/>
```
[Flutter] Flutter コントリビューション時のテストについて

# 1. はじめに

本記事は[Flutterのgithub](https://github.com/flutter/flutter)にコントリビューション（FrameworkのdartコードやSDKが対象) する時に実施するテストについての備忘録です。そのため、コントリビューションを考えている人以外、基本的に読む価値がありません。

# 2. 事前準備

ソースコードをクローンして、`dart-sdk`だけダウンロードします。

```
$ git clone https://github.com/flutter/flutter.git
$ cd flutter
$ ./bin/flutter
```

# 3. Flutter Framework に手を加える場合

```
$ git clone https://github.com/flutter/tests.git
$ cd tests
$ pushd ../flutter/dev/customer_testing && pub get && popd
$ ../flutter/bin/cache/dart-sdk/bin/dart ../flutter/dev/customer_testing/run_tests.dart --skip-template --verbose registry/*.test
```

# 4. Flutter SDK に手を加える場合

## テストコード

Flutter SDKのテストコードはhttps://github.com/flutter/flutter/tree/master/packages/flutter_tools/test 以下にあります。ここにあるテストを流して修正による結果NGが出ていないことを確認しておきます。

## ユニットテスト

```
$ cd packages/flutter_tools
$ ../../bin/cache/dart-sdk/bin/pub run test -rcompact -j4 --no-color test/commands.shard
```

## 各コマンドのテスト

Linux, macOS環境で試しましたが、いくつかはGoogleのCI環境じゃないと必ずエラーになる気がします。

```
$ cd packages/flutter_tools
$ ../../bin/cache/dart-sdk/bin/pub run test -rcompact -j4 --no-color test/commands.shard
```
試験 AI-100: Designing and Implementing an Azure AI Solutionに合格した

[AI-900](https://qiita.com/allforbigfire/items/7ead3377171b4bf1479a)に続いて、AI-100試験に挑戦しました。
ぎりぎりでしたが幸い合格し、Microsoft Certified: Azure AI Engineer Associateになりました。独学で苦労したので、まとめておきます。

### 勉強の方法

Microsoft、Azureの資格試験対策のとっかかりは、公式に指定されている範囲のMS Learnとドキュメントが鉄板です。
[試験 AI-100: Designing and Implementing an Azure AI Solution](https://docs.microsoft.com/ja-jp/learn/certifications/exams/ai-100)

しかしAI-900試験の際、MS Learnのラーニングパスだけでは試験範囲に実際足りなくて、たまたま読んでいたQiita記事のおかけで合格できました。

そこで、AI-100に合格された方々の記事を参考にさせていただきました。

[【合格体験記】Azure AI Engineer Associate になりました！](https://qiita.com/torisankanasan/items/55a51993d2959f7cad1f)
[Azure AI Engineer Associate 取得の記録](https://qiita.com/knowsun/items/bc0cb6a05bde03a86bf7)
※ 独自に作成された一つ目のMS Learnに取り組みました。
[Azure の資格を全部とった話 #AI-100編](https://bigriver.jp/?p=7769)
[【Microsoft Azure資格】Azure AI Engineer Associate (AI-100)を取得した話【2020年度最新】](https://www.simpletraveler.jp/2020/10/03/microsoftazure-certificate-report-azureaiengineerassociate/)

また、株式会社キカガク、トレノケート株式会社が開講している『AI-100対策講座』カリキュラムの項目を確認しました。
対策講座なので、カリキュラムとして挙げている項目は試験にでる確度が高いはずと考えました。

コロナ禍で毎日定時あがり、週に一度は休業日になったしまったので、こつこつ上述のサイトやMS Learn、購入したUdemy教材に取り組んでいきました。

### 活用したUdemyの教材

対策教材は英語のものしか見つかりませんでしたので、評価が多かったこの教材[AI-100 Designing And Implement Azure AI Solution Exam Prep](https://www.udemy.com/course/ai-100-designing-and-implement-azure-ai-solution-exam-prep-certacademy/)を選びました。タイミングよくセールでしたので、¥18,600　→　セール価格 ¥1,200 で購入でき大変助かりました。

![udemy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155894/dafb2e5d-6382-6c59-4d2e-1464250bb456.png)

英語なこともあり、とりあえず回答して解説が表示される状態にして、問題文と解説をブラウザで日本語に翻訳し、どういう形式の問題が出て、何が問われるポイントなのかを理解するように努めました。
手間がかかって、演習テスト1と演習テスト2しか読めませんでした。すべて出来ていたら、後述のようなギリギリの点数にならなかったと思います。

### 受験料と費用

受験料は、0円でした。
Microsoft Ignite September 2020、ありがとうございます。

![受験料.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155894/3b686cda-5b59-8486-2af5-487a2e1de904.png)

よって実際にかかった費用は、Udemy教材の¥1,200だけです。

### 試験結果
合格点すれすれで、本当にギリギリでした。
![IMG_4790.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155894/33963d23-c793-4baf-258b-2b89cb27f576.jpeg)
全然知らない内容が出たので、試験中に本当に慌てました。
あと、シチュエーション問題というのでしょうか、後から見直しが出来ない出題形式の問題があって、心臓が縮む思いで完了ボタンをクリックしました。

### 感想

会社が負担してくれる訳でもないので、一発合格出来てよかったです。
MS Learnが試験範囲として提示しているラーニング パスが4個だけなのは、明らかに少ないので、そこはMicrosoft公式でなんとか改善してほしいと思いました。

なおこのAI-100試験ですが、今後AI-102に変わっていくそうです。受験を考えておられる方は、次の公式ブログを確認してください。
英語が得意な方は、ベータ試験が始まったらすぐ申し込んでみるのも良いかと思います。たぶんベータ試験なので受験料が安くなるはずです。
[Level up with Microsoft Certified: Azure AI Engineer Associate](https://techcommunity.microsoft.com/t5/microsoft-learn-blog/level-up-with-microsoft-certified-azure-ai-engineer-associate/ba-p/2080078)
[We’re taking Azure certifications for data and AI to the next level](https://techcommunity.microsoft.com/t5/microsoft-learn-blog/we-re-taking-azure-certifications-for-data-and-ai-to-the-next/ba-p/1868370)

業務では必要になる機会はないと思うのですが、個人開発でスマートスピーカーやLINE Botに取り組んでいるので、今回学んだAzureのAIサービスを活かしていきたいと思います。
$ rails db:seedを用いて初期データを格納


#この記事/メモについて（はじめに）
Twitterの呟きやそれに対するリプライ・コメントは、「ユーザーが送信した情報」をデータとしてデータベースに保存する、と言った仕組みのものです。
しかし、データベースへ格納するデータは必ずしもユーザーや第三者が投稿・送信してきたものだけとは限りません。

例えば、自分が行ったことのあるおすすめの国について紹介するWebサイトを制作しようとした時。
このサイトでは、ユーザーが「ここの国はおすすめだよ！」「この地域の料理、とても美味しかった！」と呟いたものではなく、開発者のみなさんが現地で感じた思いやおすすめのポイントなどを掲載したいですよね。

本記事では、そんな方々のために、開発者が裏側からデータを格納する方法についてご紹介しようと思います。


##手順 （２Stepで簡単にできます！）
裏側からのデータの格納は、

①seedファイルに保存したい初期データを記述
②「$ rails db:seed」というコマンドを入力する

という実に簡単な方法で行うことができます。
①番の記述の仕方を抑えてしまえば、特に難しい内容はありません。以下で詳しく説明していきます。

###Step1　seedファイルに保存したい初期データを記述

例として、Countries（プロダクトに合わせて変更）テーブルに開発者側からデータを入れる場合を考えます。
Countriesテーブルには、nameカラムと、説明のためのbodyカラム、さらに滞在日数を表すdayカラムとその予算(万円)を示すbudgetカラムが存在しているとします。


ここでは、表のような情報を開発者が入れる初期データとして保存していこうと思います。

| ID |   name  　  |     body                 |      day    |   budget  |
|:--:|:-----------:|:------------------------:|:-----------:|:---------:|
| 1  |   韓国 　    |  低予算で初海外旅行におすすめ！ |    3日      |    5      |
| 2  | スペイン 　   |  自然より建物好きならヨーロッパ！ |    1週間     |    15     |
| 3  | シンガポール   |  チキンライスは外せない！      |    4日半     |    10     |

保存形式は以下の通りです。文字列と整数が混在している場合を考えます。
・name　→　文字列（string型）
・body　→　長い文字列（text型）
・day　→　文字列（string型）
・budget　→　整数（integer型）


このようなデータをCountriesテーブルに保存したい時、まず`db/seeds.rb`内に以下のように記述します。

```ruby:db/seeds.rb
Country.create!(name: '韓国', body: '低予算で初海外旅行におすすめ！', day: '3日', budget: 5)
Country.create!(name: 'スペイン', body: '自然より建物好きならヨーロッパ！', day: '1週間', budget: 15)
Country.create!(name: 'シンガポール', body: 'チキンライスは外せない！', day: '4日半', budget: 10)
```


レコード1つにつき1行分必要となるイメージです。（たくさんのレコードを保存させたい場合に合わせて、より効率の良い書き方もあります。他にも様々な書き方があるので、是非調べてみてください！）

 

💡1point豆知識💡
**整数(integer型)で保存するbudgetについて、値を「""」や「''」で囲っていないこと**に注意してください。
→seedsファイルに限らず、プログラミングの世界ではダブル/シングルクオーテーションを用いて囲ったものは基本的に**文字列として認識されてしまう**ので、エラーが生じてしまいます。


###Step2　seedファイルに記述した内容をデータベースに反映させる

ターミナル、またはコマンドプロンプトで以下のコマンドを実行することで、db/seeds.rbに記した内容をデータベースに反映することができます。

```
$ rails db:seed
```

以上です！簡単でしたね！

###Step3　データベース内のデータを確認/削除する

データベースに保存されているデータについて**確認/削除**したいとき、`$ rails c`というコマンドを実行します。（`$ rails c`を終わりにする際は`exit`と入力してEnterを押してください。）

こちらの内容はseeds.rbを用いて初期データを格納する場合以外でも頻出のコマンドとなるので、別記事に軽くまとめるつもりです。(気が向いたら。。)

======

`$ rails c`は頻出のコマンドとなるので、**データの確認/削除は「$ rails c」!!**と自分に三回言い聞かせましょう。

####データの確認

以下のようにコマンドを入力してください。Countriesテーブルに保存されているデータが出力されるはずです。

```
$ rails c
irb(main):001:0> Country.all

# => 保存されているデータの出力（確認）
```

####データの削除

以下のようにコマンドを入力すると、今度はCountriesテーブルに保存されているデータを**全て削除することができます。**

```
$ rails c
irb(main):001:0> Country.delete_all

# => 保存されているデータの削除
```

#参考

railsのseedの書き方いろいろ
https://qiita.com/takehanKosuke/items/79a66751fe95010ea5ee

【Rails】CarrierWave + seedで初期データに画像ファイルを投入する
(CarrierWaveをすでに実装している方のうち、初期データに画像を入れたい方はこちらの記事が大変わかりやすいのでぜひ見てください！)
https://remonote.jp/rails-carrierwave-seed
【markdownlint】設定詳解

## はじめに

VSCode拡張機能の[markdownlint](https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint)をしばらく使っていましたが、特に設定をしていませんでした。
普段Hugoで[記事](https://ashiatoblog.com)を書く中で、**HTMLタグの使用制限**や**文書頭H1**のlintを停止したいと思い[公式ドキュメント](https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint)を参照したところ、他にも便利そうな機能があったため、ピックアップしました。

## 対象読者

* VSCodeユーザ
* すぐに答えが知りたい人
* ノンプログラマ

そうでない人は[公式ドキュメント](https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint)へどうぞ。
markdownのコーディングルールは[こちら](https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md)。

## 選択的にlintを停止する方法

### ユーザ・ワークスペース・フォルダに対して適用

`settings.json`に下記を追記する。

```jsonc:settings.json
"markdownlint.config": {
    // インラインHTMLの制限を解除
    "MD033": false,

    // H1がなくてもOK
    "MD041": false,
}
```

もしくはルートディレクトリ下の`.markdownlint.json`に下記のように記述します。

ただしこの場合、`settings.json`は無効となり、後述の方法で継承することもできないと思われます。(確認不足かも)

```jsonc:.markdownlint.json
{
  "MD033": false,
  "MD041": false,
}
```

`.markdownlint.json`適用の優先順位は以下で、構成が見つかるとそれより下位の構成は無視されます。
つまり自動的に継承はされないため、継承したい場合は明示します。

1. 同一ディレクトリ内
2. 親ディレクトリ内
3. プロジェクトルート
4. settings.json
5. デフォルトの構成

### 一部に適用

一部のみに例外を適用したい場合は以下のように設定します。

```md
例: 画像の代替テキストを省略する

<!-- markdownlint-disable MD045 -->
![](path_img)
<!-- markdownlint-enable MD045 -->
```

## 継承

`"extends": "相対パス"`で`.markdownlint.json`を継承します。

以下、例が続きます。

```bash
root\
  ├ .markdownlint.json
  ├ dir1\
  │   └ file1.md
  └ dir2\
      ├ .markdownlint.json
      └ file2.md
```

```jsonc:.markdownlint.json
{
  // インラインHTMLの制限を解除
  "MD033": false,

  // H1がなくてもOK
  "MD041": false,
}
```

```jsonc:.markdownlint.json
{
  // 親ディレクトリの.markdownlint.jsonを継承
  "extends": "../.markdownlint.json",

  // 代替テキストの制限
  "MD045": false
}
```

```markdown:file1.md/file2.md
## h2

<code>inline HTML</code>

![](img)
<!-- ↑ file1.mdのみlint -->
```

正直使いどころがわかりませんが、手段として知っておく分にはよかったかなという印象です。

## まとめ

基本的には`settings.json`で`"MD001": false`などと指定しておけばいいですね。

指定すべきMarkdownのコーディングルールは[こちら](https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md)。(再掲)
【Java】java.lang.NullPointerExceptionを避ける方法

#プログラミング勉強日記
2021年1月23日
Javaでコードを書いているときに、よく出てくるNullPointerExcptionの意味と、NullPointerExcptionにならないようにする方法をまとめる。

```:java.lang.NullPointerException
Request processing failed; nested exception is java.lang.NullPointerException
```


#NullPointerExceptionとは
　参照型の変数の値にnullが格納されているとき、それを参照しようとしたときには発生する例外である。

> NullPointerException（ナル・ポインタ・エクセプション、ヌル-）は、プログラミング言語Javaにおける例外の一つである。
null値（定義されていない値）の参照型変数を参照しようとした時に発生する。NullPointerExceptionは実行時例外と呼ばれるjava.lang.RuntimeException クラスのサブクラスであるため、try-catch節による例外処理を書かなくてもコンパイルエラーは発生しない。
(引用：https://ja.wikipedia.org/wiki/NullPointerException)

　なので、以下のようなコードだとNullPointerExcptionが発生する。

```java
class Sample{
    public static void main(String[] args) {
        Integer i = null;
        i.toString();
    }
}
```

#NullPointerExcptionを避ける方法
　基本的には、参照型変数がnullかどうか判定すればいい。
　先ほどのコードではNullPointerExcptionが発生したが、参照型変数がnullの場合は処理をしないというコードに書きかえることでNullPointerExcptionをなくせる。

```java
class Sample{
    public static void main(String[] args) {
        Integer i = null;
        // i がnullの場合、処理をしない
        if(i == null) {
            return;
        }
        i.toString();
    }
}
```

　しかし、コード量が増えるほど判定は大変になるので対策方法を示す。

1. null以外の値で変数を初期化する
2. 配列は空で初期化する
3. 戻り値にnullを返さない

　この3つを意識することで、NullPointerExcptionが発生しにくくなると思う。

#参考文献
[【Java】java.lang.NullPointerException](https://tech.pjin.jp/blog/2017/09/05/%E3%80%90java%E3%80%91java-lang-nullpointerexception/)
自分用メモ_超TypeScript入門 完全パック(2021)アウトプット記事(Typescript + Node.jsのプロジェクト作成手順)

Udemyの超TypeScript入門 完全パック(2021)のアウトプット記事です。
本記事ではtypescriptのみ扱うプロジェクトについて解説します。

#Node.jsをインストール
まずは下記サイトでNode.jsをインストールします。
https://nodejs.org/ja/

Node.jsはサーバーサイドのイメージが強いですがクライアントサイドでも必要らしいです。

npmのことも書かれているので詳しくはこちらをご覧ください。
[Node.jsとはなにか？なぜみんな使っているのか？](https://qiita.com/non_cal/items/a8fee0b7ad96e67713eb)

#npmをインストール
続いてnpmというNode.jsのパッケージ管理ツールを下記コマンドをコマンドプロンプトかターミナルに入力し、インストールします。
`npm install -g typescript`
`-g`はディレクトリを指定せずに全てのフォルダにtypescriptを適用させるという意味です。

- Nodeバージョン確認コマンド`node --version`
- npmバージョン確認コマンド`npm --version`

- インストールが終えたらフォルダを作成し、vscodeなどのエディタで開いてください

#コンパイルと実行
- コンパイル
- 
javascriptにコンパイルするには```npm tsc ファイル名```でコンパイルします。
(tscコマンドはnpmをインストールすると使えるようになります)

- 実行

```npm node ファイル名```で実行できます







[超TypeScript入門 完全パック(2021)](https://www.udemy.com/course/typescript-complete/)
GolangでGoogle Calender APIを使って日本の祝日情報を取得する

祝日の一覧が欲しいなと思った時にGoogle Calendarから取得する方法を調べたので
まとめておきたいと思います。
GolangでGoogle Calender APIを使って取得します。

## はじめに
[google calender api ドキュメント](https://developers.google.com/calendar/quickstart/go?hl=ja)
にgolangで利用する時のクイックスタートが乗っているので、参考に進めていきます。


#### 1. 作業ディレクトリの作成
```
$ mkdir google_calender
$ cd google_calender/
```

#### 2. Google APIを利用するためのcredentialsを取得
![スクリーンショット 2021-01-22 21.18.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6510/6bfc8ca5-4322-2282-025a-ec93703183d4.png)
「Enable the Google Calender API」をクリックして進むとキー情報が書いてあるcredenrial.jsonがダウンロードできるので、作業ディレクトリに置きます。

#### 3. 必要なモジュールの追加
ドキュメントに従ってモジュールを追加していきます

```
$ go get -u google.golang.org/api/calendar/v3
$ go get -u golang.org/x/oauth2/google
```
#### 4. 実行ファイル作成
```
$ touch quickstart.go
```
[quickstart.go](https://github.com/googleworkspace/go-samples/blob/master/calendar/quickstart/quickstart.go)
githubにコードがあるので、コピペします。

mod初期コマンド

```
$ go mod init google_calender
```

ビルドします

```
$ go build
```

#### 5. tokenの取得
この状態で実行するとURLが表示されるので、実行した状態でブラウザにコピペして利用を許可します。

```
$ go run quickstart.go
https://accounts.google.com/o/oauth2/auth...
```

利用許可を進めていくと最後に「このコードをコピーしてアプリケーションに貼り付けてください」と表示されるので、先ほどの実行した状態のコンソールにコピペします。
成功すると「token.json」というファイルが出来ていると思います。
ここまででquickstartを実行する準備が整いました。

#### 6. 祝日を取得するようにコードを修正する
quickstartのままだと利用許可したアカウントのカレンダーに登録されている予定を取得するようになっています。
これを祝日が取得できるカレンダーから取得するようにします。

quickstartで使用されている

```:L.109
events, err := srv.Events.List("primary")
```
のドキュメントを見ると
[golang google api doc](https://godoc.org/google.golang.org/api/calendar/v3#EventsService.List)
パラメータでcalender idを渡せるようです。
※primaryはアカウントのプライマリカレンダー

調べた所、日本の祝日用のcalender idが

```
ja.japanese#holiday@group.v.calendar.google.com
```

こちらになるようです。

先ほどのL.109のcalender idを書き換えます。

```:L.109
events, err := srv.Events.List("ja.japanese#holiday@group.v.calendar.google.com")
```

#### 7. 実行して祝日のリストを取得する
実行します

```
$ go run quickstart.go
Upcoming events:
建国記念の日 (2021-02-11)
天皇誕生日 (2021-02-23)
春分の日 (2021-03-20)
昭和の日 (2021-04-29)
憲法記念日 (2021-05-03)
みどりの日 (2021-05-04)
こどもの日 (2021-05-05)
海の日 (2021-07-22)
体育の日 (2021-07-23)
山の日 (2021-08-08)
```

取れました！！！！
quickstartでは現在時刻から10件取得するようになっているので、L.110のパラメータを修正すれば期間や件数を変更できます。

## おわりに
簡単に祝日の一覧を取得する事ができました！！！！！
UnityでTwitter投稿画面を開く


`"twitter://post?message="` の後にテキストを入れる
テキストやURLに全角文字が含まれている場合は、stringの文字列をUriにエンコードする必要がある

```
string url01 = "twitter://post?message=令和";
Uri url02 = new Uri(url01);
Application.OpenURL(url02.AbsoluteUri);
```

↓URLのテキストに入れるハッシュタグや改行の書き方
https://qiita.com/ampersand/items/2ec01bd5c5b64f1e67bf
Axiosで外部ファイルをロードしてFileにする /  Data URI schemeをFileにする

- 外部リソースをAxiosでロードし`File`オブジェクトに変換する
- Data URI schemeを`File`オブジェクトに変換する

```javascript:uriToFile関数
import axios from 'axios'

function uriToFile(uri, fileName) {
  if (!uri) return Promise.resolve(null)
  return uri.startsWith('data:')
    ? convertDataUriToFile(uri, fileName)
    : loadUriToFile(uri, fileName)
}

function convertDataUriToFile(dataUri, fileName) {
  const byteString = atob(dataUri.split(',')[1])
  const mimeType = dataUri.match(/(:)([a-z/]+)(;)/)[2]

  const length = byteString.length
  const content = new Uint8Array(length)
  for (let i = 0; length > i; i++) {
    content[i] = byteString.charCodeAt(i)
  }

  return Promise.resolve(
    new File([content], fileName, {
      type: mimeType,
    })
  )
}

async function loadUriToFile(uri, fileName) {
  const response = await axios.get(uri, {
    responseType: 'blob',
  })
  return new File([response.data], fileName, {
    type: response.data.type,
  })
}
```

```javascript:使い方
uriToFile('https://example.com/example.png')
  .then(file => ...)

uriToFile('data:image/png;base64,iVBORw0KGgoAAA...')
  .then(file => ...)
```
[Rails] カラムのオプションと型

オプション|用途
--------|---------------------------------
null: false |「not null制約（nullはNG）」をつける
index: true |インデックスをつける
unique: true |一意制約をつける。
t.integer|カラムの型を数値型に指定
default: 100|初期値（100）を設定


型 |用途
-----|--------------------------------------
string| 文字列型
text |テキスト（不定長文字列）型
integer |整数型
float |浮動小数点数型
decimal |固定長整数型
datetime |日時型
timestamp| タイムスタンプ型
time |時刻型
date |日付型
binary |バイナリ文字列型
boolean| 真偽値型
references| 他のテーブルへの外部キーの定義、_id が付いた整数
VB.netのプロジェクトにlog4netを使用してログ機能を追加

#まとめ
log4netを使うためには
①プロジェクトにlog4netを追加（NuGet経由）
②ログが必要のモジュールにAssemblyInfo.vbファイルに追記
③Exeプロジェクトにlog4netのconfigを追加

#NuGetでlog4netをプロジェクトに追加
（ネットにたくさんあるので割愛）

#AssemblyInfo.vb
基本的にはEXEモジュールにこのファイルに下記内容を追加すればよい。
**※クラスライブラリでもログを出力するために、
クラスライブラリプロジェクトのAssemblyInfo.vbに
下記の内容の追加は必要**

```xml
<Assembly: log4net.Config.XmlConfigurator(ConfigFile:="log4net.config", Watch:=True)>
```
**※ここでlog4netがどの設定ファイル（ここはlog4net.config）を使用するかを指定している。
　指定しない場合、下記のようにApp.configがlog4netの設定ファイルとして使われる。**

A.exe（APPメイン処理、B.dllを経由してC.dllを使っている）
B.dll（C.dllを使っている）
C.dll（ログを出力したい処理がある）

この場合、上記内容をAssemblyInfo.vbに追加するのはA.exeとC.dllになる。

#log4net.config
log4netを設定するには
A.exeのlog4net.configのみを下記内容を追記すればよい。
①Aのプロジェクトに「新しい項目」を追加して、
　「共通項目」→「全般」→「アプリケーション構成ファイル」を選択し
　「名前」に「log4net.config」を入力して「追加」
②「出力ディレクトリにコピー」を「常にコピーする」を選択
※log4net.configを作成しない場合、A.exeのプロジェクトのApp.configに追加してもよい。
　プロジェクトが作成される際、<プロジェクト名>.exe.configに自動的に追加されるらしい。

```xml
  <configSections>
    <section name="log4net"
      type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
  </configSections>

  <appSettings>
    <!-- log4net 内部のデバッグメッセージを出力 -->
    <add key="log4net.Internal.Debug" value="true" />
  </appSettings>

  <log4net>

    <!-- ファイル出力用のアペンダ（日付でローテーション） -->
    <appender name="DailyFileAppender"
      type="log4net.Appender.RollingFileAppender">
      <!-- ログファイルの切替 { サイズ: Size, 日付: Date } -->
      <param name="RollingStyle" value="Date" />
      <!-- ファイル名 -->
      <param name="File" value="log.txt" />
      <!-- ファイル書き込み { 追記: true, 上書き: false } -->
      <param name="AppendToFile" value="true" />
      <!-- 出力文字列のフォーマット -->
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%-5level %date [%thread] %c %line - %message%newline" />
      </layout>
    </appender>

    <!-- デフォルトの出力設定 -->
    <root>
      <level value="ALL" />
      <appender-ref ref="DailyFileAppender" />
    </root>
  </log4net>
```
EntityFramewofk Coreで自動採番となっているテーブルで指定のIDを追加したい

#はじめに
現在利用しているアプリを新規アプリに変更するにあたってSQL Serverに新しくデータベースを作って、そこに元のデータをいれようと思っていました。
テーブルをコードファーストで作っていたのですが、これだと旧テーブルから新テーブルにデータを移行する際に、IDが変わってしまうという問題がありました。
そこで、いろいろと調べていると、SET IDENTITY_INSERT [table名] ON を行えばいいということが分かり実装してみました。

#問題が起きました
Master_Staff(旧テーブル)　⇒　Main_User(新テーブル)
蛇足ですが、昨今の"Master"は使わないようにしようという流れにあわせて、新規アプリでテーブル名を変更することにしました。

```C#
    internal async Task InsertMainUserAsync(newDBContext dbContext, List<Master_Staff> MasterStaffs)
    {
        await Task.Run(() =>
        {
            foreach (var s in MasterStaffs)
            {
                dbContext.Main_Users.Add(new Main_User()
                {
                    Main_UserId = s.Master_StaffId,
                    UserName = s.StaffName,
                });
            }
            dbContext.Database.ExecuteSqlRaw("SET IDENTITY_INSERT Main_Users ON");
            dbContext.SaveChanges();
            dbContext.Database.ExecuteSqlRaw("SET IDENTITY_INSERT Main_Users OFF");
        }
    }
```
SqlException: IDENTITY_INSERT が OFF に設定されているときは、テーブル 'Main_Users' の ID 列に明示的な値を挿入できません。
というエラーが起きました。

#解決
いろいろと調べると、Microsoft Documentに[生成されるプロパティに明示的な値を設定する](https://docs.microsoft.com/ja-jp/ef/core/saving/explicit-values-generated-properties)というページがありました
そこにあるSampleは以下の通り

```C#
using (var context = new EmployeeContext())
{
    context.Employees.Add(new Employee { EmployeeId = 100, Name = "John Doe" });
    context.Employees.Add(new Employee { EmployeeId = 101, Name = "Jane Doe" });

    context.Database.OpenConnection();
    try
    {
        context.Database.ExecuteSqlRaw("SET IDENTITY_INSERT dbo.Employees ON");
        context.SaveChanges();
        context.Database.ExecuteSqlRaw("SET IDENTITY_INSERT dbo.Employees OFF");
    }
    finally
    {
        context.Database.CloseConnection();
    }
}
```
どうやら、同じ接続内でSET IDENTITY_INSERTを行わないとエラーになるようでした。
ということで以下のようにコードを変更したらうまくいきました。

```C#
    internal async Task InsertMainUserAsync(newDBContext dbContext, List<Master_Staff> MasterStaffs)
    {
        await Task.Run(() =>
        {
            foreach (var s in MasterStaffs)
            {
                dbContext.Main_Users.Add(new Main_User()
                {
                    Main_UserId = s.Master_StaffId,
                    UserName = s.StaffName,
                });
            }

            //ExecuteSqlRawとSaveChangesの部分を以下のように変更しました。
            dbContext.Database.OpenConnection();
            try
            {
                dbContext.Database.ExecuteSqlRaw("SET IDENTITY_INSERT Main_Users ON");
                dbContext.SaveChanges();
                dbContext.Database.ExecuteSqlRaw("SET IDENTITY_INSERT Main_Users OFF");
            }
            finally
            {
                dbContext.Database.CloseConnection();
            }
        }
    }
```

分かってしまえばなんてことないことですが、分かるまでは「なんで？」と思って、他にいろいろと原因を探して、無駄な時間を費やしてしまいます。
同じように困っている人がいれば、参考となればと思います。
AVFoundation　音再生

## 音再生方法



まず　AVFoundation をインポート

```viewController.swift
import UIKit
import AVFoundation

class ViewController: UIViewController,AVAudioPlayerDelegate {

    var player :AVAudioPlayer!

```

まず、音ファイルをXcodeに追加。追加するのはここ！!
今回は　
umbrella と souziki が入っていますね。
![スクリーンショット 2021-01-23 21.07.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562721/2909f8de-4473-c600-e449-b3a16370cd6e.png)



音声を呼び出す用の関数を定義!

```viewController.swift

    public func prepareSound() {
        let soundFilePath = Bundle.main.path(forResource: "umbrella", ofType: "mp3")!
        let sound:URL = URL(fileURLWithPath: soundFilePath)
        do {
            player = try AVAudioPlayer(contentsOf: sound, fileTypeHint: nil)
            player?.delegate = self
        } catch {
            print("イエラー")
        }
        player?.delegate = self
        player?.prepareToPlay()
    }
   
```

viewDidLoad()に関数を記入


```viewController.swift
    override func viewDidLoad() {
        super.viewDidLoad()

        prepareSound()
        
    }

```

あとは、ボタンなど、呼び出したいところで下記のオードを書けば

```viewController.swift
    @IBAction func button(_ sender: Any) {
        
        if ((player?.isPlaying) != nil) {
            player?.stop()
            player?.currentTime = 0
        }
        player?.play()
    }
```

現在、選択私の違いによって出る音の変わる仕組みを製作中。
【合格体験記】Pythonエンジニア認定基礎試験（2021/01/23）

#合格しました！
1月23日にPythonエンジニア認定基礎試験を受験し、無事合格しました！
この記事では、Pythonエンジニア認定基礎試験の**申込方法・勉強法・所感**を紹介します。

#筆者のバックグラウンド
文系大学出身の20卒です。都内のIT企業で働いています。

◆業務経歴
　4月　　　　主にPython初級レベルの新人研修を受ける
　5月　　　　部署でJava研修を受ける
　6月～　　　環境移行・オープン化案件でテストや運用監視業務を担当

入社前や新人研修でPythonの基礎を学び、簡単な関数を組めるレベルになりました。
しかし昨年5月でPythonの勉強を中断したため、年末にはPythonの書き方を大方忘れてしまっている状態でした。
一方、Pythonの勉強を中断している間にJavaを勉強し、JavaSilverの資格を取得しました。
つまり資格勉強開始時には、**Python初心者・Java中級者**程度のプログラミングスキルでした。

#申し込み方法

**①[OdesseyIDの作成](https://cbt.odyssey-com.co.jp/cbt/registration/index.action)**
1分ほどで登録が完了する簡単なものでした。
申し込みには必要ありませんが、受験時や結果確認に必要です。

**②[試験会場を探す](https://cbt.odyssey-com.co.jp/place.html)**
ざっと見たところ、パソコン教室が会場になっている場合が多いようです。
毎日受験できる会場もあれば、土日のみの会場もあります。

会場を選択すると、「※受験希望の方は、試験会場へお問い合わせください」と書いてありますが、結局教室のHP（[ISAオンラインショップ](https://www.isa-onlineshop.net/user_data/testcenter/index.php)等）から直接申し込むことになります。
会場と日時を選択すると、支払い方法の案内が来ます。銀行振込を指定されました。
支払いを済ませたところで申し込み完了です！

#勉強法
使用教材は3つです。

①**[スッキリわかるPython入門](https://book.impress.co.jp/books/1118101169)**（学習期間：3日）
Pythonが全くの初心者ではなかったうえに、プログラミングの基礎知識はJavaで身につけていたので一瞬で終わりました。
この教材があればPythonについて一通りは学べるので、プログラミング初心者・他言語経験者におすすめです。
Pythonの知識が少しでもある人には少々物足りない内容だと思います。

②**[Pythonチュートリアル第3版](https://www.oreilly.co.jp/books/9784873117539/)**（学習期間：1週間）
Pythonエンジニア認定基礎試験公式の教材で、試験概要にてどの章から何問出るかまで公開されています。

試験概要：https://www.pythonic-exam.com/exam/basic

これが本当に曲者。内容が難しいというか、翻訳がおかしいというか、とにかくわかりづらくて腹が立ちます。
半年前に購入したときは、本当に読めなくて途中でギブアップしました。
Javaをしっかり学んだ今でも7割くらいしか理解できません。

でもそれでいいんです。
試験対策という観点だと、この教材は流し読み程度で十分。
事実試験概要の動画で公式の人が、「この本は学校の教材でいう教科書だから、勉強は問題集(他の教材)を使ってください」とおっしゃっていますから。

```python
if この教材を読んだときに言っていることが1ミリもわからない:
    スッキリわかるPython入門等他教材で再度勉強
else:
    教材での勉強終了
```

でいきましょう！

③**[DIVE INTO EXAM](https://exam.diveintocode.jp/exam)**（回数：3回）
会員登録するだけで受けられる無料の模擬試験です。
1回目を受験した時点で800点(合格700点)だった時点で察しました。

(簡単と聞いていたけどここまでとは…)

他言語履修してたらPython全く分からなくても合格できるのでは、レベルです。
結局、2回目も800点、3回目925点で試験に臨みました。

#所感
模試よりは多少難しかったですが、模試で合格点を取れれば十分合格できると思います。
60分40問の試験でしたが、見直しも含め30分ほどで終わり、結果875点でした。

気を付けるべきことが2点ほどあります。

①**メモ用紙は使えない**
まあメモするほどのこともないですけど、メモできるつもりでいたのでちょっと動揺しました。

②**地味に「複数選べ」がある**
これは見直しの時に気が付いて一命を取り留めました。
複数選択で1つしか選んでいなくても通知されないのでご注意を！

#おわりに
Pythonって簡単に使えるのが売りだから、なかなか中上級レベルの試験を作るのは難しいんですかね…
もうちょっと試験の質を高めていただきたいところですね。

最後まで読んでいただき、ありがとうございました。
皆さんが合格できますように！
GG ACPRでreplayファイルをフォルダ分けするバッチ

## 機能
(以前公開したバージョンに不具合ありました。修正しました。ごめんなさい ）

Steam版 Guilty Gear xx Accent Coreで
Network対戦を行ったreplayファイルを日付フォルダに整理するバッチ。

ACPRのメニューからreplayを選ぶと、全て出てきてまともに選択できない。
しかしアプリ的には実フォルダの階層をブラウザする機能が備わっているので、
フォルダ階層を分けしてあげれば、そのように表示できる。
これを自動化するツールを作った。

## やること

「コード」に記載したコードをtextファイルに貼り付けて保存。
拡張子を「.cmd」に変更。

実行する。

デスクトップにおいて適当にダブルクリックしてもいいと思うし、
一日一回定期実行するようにしておいてもいいかもね

## コード
（直近7日分はcurrentに表示し、それより古いものはarchiveフォルダに移動するように修正）

```
@echo off
setlocal enabledelayedexpansion

set cur_dir=%~dp0
set dir_path=%HOMEPATH%\Documents\ARC SYSTEM WORKS\GGXXAC\Replays

cd %dir_path%

rem If your location is other than Japan, you should change code that is at after line.
rem Example for US. 'set today=%date:~10,4%%date:~7,2%%date:~4,2%'  
set today=%date:/=%

set archivedir=archive

if not exist %archivedir% (
    mkdir %archivedir%
)

for %%i in (*.ggr) do (
    set filename=%%i
    set stamp=!filename:~0,8!

    if not %today% == !stamp! (
        if not exist !stamp! (
            mkdir !stamp!
        )
        move /Y "!filename!" !stamp!
    )
)

set /a count=0
set /a n=0

for /d %%i in (20*) do (
    set /a count=count+1
)

echo %count%
set /a target=count-7

for /d %%i in (20*) do (
    set /a n=n+1
    if not !n! gtr %target% (
        move /Y %%i %archivedir%
    )
)

cd %cur_dir%
```

## こんな感じ

![replay.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1049132/82cfdc48-b80e-1516-7de6-b7087a96ebb6.png)

## 英語版 ( for US location )
https://twitter.com/Skeletal_Minion/status/1354657367514894337

thanks Skeletal Minion (@Skeletal_Minion)
CSS変数に色のHEX値を入れると rgba() が使えないので RGB値も変数にする

# css変数に色を格納する時はRGB値も入れればOKという話

下記の記述は意図した結果になりません。

```scss:
--color_red: #f00;

.red{
  // rgba(#f00, 0.5) と書いたのと同じなので反映されない
  color: rgba(var(--color_red), 0.5);
}
```

下記は透明度50%の赤になります。

```scss:
--rgb_red: 255, 0, 0;

.red{
  color: rgba(var(--rgb_red), 0.5);
}
```

## root に色の変数を格納しよう

こんな感じに色の一覧を作っておきます。

```sass
$colors:(
  red:(
    base: #f00,
    light: #f33,
    dark: #c00
  ),
  blue:(
    base: #00f,
    light: #33f,
    dark: #00c
  )
);
```

:root に色の変数を書き出します。

```sass
@use "sass:color";

:root{
  @each $name, $color in $colors) {
    @each $type, $code in $color {
      @if $type == "base" {
        --root-color_#{""+$name}: #{$code};
        --root-rgb_#{""+$name}: #{color.red($code)}, #{color.green($code)}, #{color.blue($code)};
      } @else {
        --root-color_#{""+$name}-#{$type}: #{$code};
        --root-rgb_#{""+$name}-#{$type}: #{color.red($code)}, #{color.green($code)}, #{color.blue($code)};
      }
    }
  }
}
```

出力結果。

```css
:root{
  --root-color_red: #f00;
  --root-rgb_red: 255, 0, 0;
  --root-color_red-light: #f33;
  --root-rgb_red-light: 255, 51, 51;
  /* ...省略 */
}
```

dart-sass での方法です。
lib-sass では使えません。
IPA プロジェクトマネージャ試験　合格体験記（2020年秋）

# IPA プロジェクトマネージャ試験　合格体験記（2020年秋）

　無事受かったので、勉強したことなどをまとめていきます。


## 背景・目的・読み手

### 背景
　2020年春にプロジェクトマネージャ試験を申し込んだものの流れてしまい、2020年秋試験を受け無事合格したので、その時のノウハウをまとめておきます。

### 目的
- 勉強方法の振り返り
- これから受験する方の参考になれば

### 読み手
　これからプロジェクトマネージャ試験を受ける方、受けてみようと考えている方


## なぜ受けるのか
　主に以下の理由から、持っていると良い試験です。

- 履歴書に書ける資格
- ある程度プロジェクトマネジメントの素養があることを示せる
    - ただし、高度な知識保有をアピールするのであればPMPのほうがよいです
- 日本語かつプロジェクトマネジメントの実績が無くても受験できる
- 所属組織の奨励金の対象になっている場合は受けて取ることをオススメ


## 勉強法
　以下のような勉強法で突破しました。
１．参考書の読み込み
２．過去問を覚える
３．書くことに慣れる

### １．参考書の読み込み
　TAC出版の参考書で突破しました。試験の傾向から午後I・午後IIの解放について具体的に記載されており大変わかりやすかったです。この参考書を2度通して読みながら分からないところを調べるような形で勉強を進めました。ポイントは以下2つです。

- 出題傾向を知る
- 受験テクニックを抑える

　後述する午前IIの傾向も踏まえると、できれば最新の参考書を読み込んだほうが良いです。参考までに2021年度のTAC出版の参考書はこちらになります。　→　[ALL IN ONE パーフェクトマスター プロジェクトマネージャ 2021年度 (情報処理技術者試験)] (https://www.amazon.co.jp/ALL-%E3%83%91%E3%83%BC%E3%83%95%E3%82%A7%E3%82%AF%E3%83%88%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%BC-%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%83%9E%E3%83%8D%E3%83%BC%E3%82%B8%E3%83%A3-2021%E5%B9%B4%E5%BA%A6-%E6%83%85%E5%A0%B1%E5%87%A6%E7%90%86%E6%8A%80%E8%A1%93%E8%80%85%E8%A9%A6%E9%A8%93/dp/4813279899/ref=sr_1_1?dchild=1&qid=1611398504&s=books&sr=1-1)

### ２．過去問を覚える
　午前IIはこれまでの傾向から、過去問から出題される問題が多いようなので、過去問を見ながら知らない用語を見たらそれに当たる、というような形で勉強しました。

　初見では解こうとしないで、問題文・選択肢・答えを読んで、知らない単語・事象については調べていくことをオススメします。知らない4択を目の前にいくら悩んでも運否天賦の域を出ませんし、何より運で当てて分かってると勘違いしてしまうほうがまずい。

　勉強の前半は自分が知っている部分・知らない部分を明確にし、整理していき、後半で知らない部分を補っていくとよいです。

　また、午前IIにはJIS Q 21500:2018（プロジェクトマネジメントの手引）やPMBOKに関する出題もありますが、両方について細部までカバーしていくと午後I・午後II対策の時間が無くなるため、出題ベース・概要から抑えていくことをオススメします。

　午後I・午後IIは設問とお手本の解法を読み込み、出題傾向を見たり、答え方のテクニックを抑えるようにしました。
　出題の意図から大きく外れると（たとえビジネス的には正解であっても）試験としては不正解となる可能性があるため、講評も読んで出題の意図を抑えるようにしました。

### ３．書くことに慣れる
　午後IIは約2,000字の論述を記述する試験となります。普段キーボードしか使っていないとこれが非常にキツイです。
　よく、午後IIは実際に書いてみたほうが良い、と言われてるのはこれが理由です。ほとんどペン持ったことがない方がいきなり2,000字の論述を書くと、ネタが尽きるより先に手が痛くなって途中で書けなくなることがあります。

　とはいえ勉強の時間をガッツリ取って午後IIの模擬試験をする余裕のない方もいると思います。そこでオススメしたいのが、「仕事や勉強でメモを取る機会を増やす」ということです。
　最近はパソコンやスマホでしかメモを取らない方もいますが、ここをノートに変えることで普段から書くことに慣れていくと良いです。紙にペンで書くことで意外と覚えます。

　手書きで2,000字記載がキツイことは知っていたので、慣れるように対策を取りましたが、それでも試験の終盤は手が痛かったですね。



## 受験テクニック

## 出題者の意図に沿った回答をする
　上記の方でも書きましたが、午後Iは出題文に回答そのもの・回答のヒントが含まれているため、そちらをベースに回答していくとよいです。
　午後IIも設問に書いてある内容を無視して自分がプロジェクトで活躍したことだけ書いても採点される可能性は低いです。きちんと設問を読み、設問にあった論述をしましょう。

## 合格ラインを知っておく
　午前I・午前II・午後Iは100点満点中60点取れれば良いです。午前Iは30題出題されるため、12問までは間違えてもセーフ、午前IIは25題出題されるため、10問まで間違えてもセーフです。
　午後Iも問題を良く読むことで解けるところだけでも半分程度あるため、そこにもうちょっと積み増せば60点は目の前です。

　ということを知っていると、分からない設問が若干多かったとしても受験中に慌てず対処することができます。午前に関してはうっかりミスを踏まえても、6～8個程度なら知らない問題があったとしても合格できるチャンスはそれなりにあると見ていいでしょう。

### 午前Iをスキップする
　[免除制度](https://www.jitec.ipa.go.jp/1_00topic/koudo_menjo.html)があるため、他の高度試験に受かっている、あるいは一度午前Iをパスしておけば、2年間は午前Iをスキップできます。受ける試験が1つ減るため、その分他の試験への勉強時間が増やせるため、午前Iをスキップできるようにしておくことは非常におすすめです。

　特に、応用情報技術者試験をお持ちでない場合は、先にそちらを取って午前Iをスキップできるようにしてから本試験を受けたほうが良いです。
go言語学習雑記2

go言語の勉強雑記その２
今回は文法

# for文
goの言語は他の言語と比べて非常に柔軟性があります。
まずは普通のfor文

```go
 	for i := 0; i < 10; i++ {
 		sum += i
 	}
```

この条件式をいじるとwhile文のような挙動を実現できます

```go

  sum1 := 1
  for sum < 1000 {
   	sum1 += sum
  }
```
これで条件式を満たさなくなるまで処理を続けます。

さらにいじると無限ループができます。

```go
  for {}
```

# if文

```go
 if x>0 {}
```
シンプルにifを書くだけ、　但し評価を()でくくる必要はないです

また、その場で変数を代入して比較を行うこともできます

```go

if i:=3; i<4 {
  // 処理 
}
```

# switch文
switch文は評価される変数を省略できる。

```go
 	t := 11
 	switch {
  	case t < 12:
  		fmt.Println("Good morning!")
  	case t < 17:
  		fmt.Println("Good afternoon.")
  	default:
  		fmt.Println("Good evening.")
  	}
```
なおbreakは自動で挿入されるため書く必要はない


# defer文
関数の呼び出し順序を操作する文法。

defer文に実行したい関数を渡すと、呼び出し元の処理が終わった段階で実行される。

```go
func main() {
 	defer fmt.Println("world")
 	fmt.Println("hello")
}

```
main関数が終了した時点で defer文の関数が実行されるため出力される文字列は
```
hello
world
```

になる。

deferはstackで実行する関数の順番を操作するので、

```go
 	fmt.Println("counting")
 
 	for i := 0; i < 10; i++ {
 		defer fmt.Println(i)
 	}
 
 	fmt.Println("done")
```
上記の場合は

```
counting 9 8 7 6 5 4 3 2 1 0 done
```
となります。
stack は LIFO になるので、入れた順番とは逆の順番で出力されるので、上記のような結果になります。


# 最後に
defer文の使いどきがわからない。下手に使うと可読性が落ちそうなのでチーム開発でのルール決めの難しいそう。
Ruby on RailsでWebpackerのエイリアスを設定する方法

```javascript:config/webpack/environment.js
const { resolve } = require('path')

environment.config.merge({
  resolve: {
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      '@': resolve('app/javascript/packs'),
      '&': resolve('app/javascript/packs/components'),
    },
  },
})
```

サーバーの再起動が必要です。
ラスタータイルのつくりかた（2022年版）

:::note info
PMTiles全盛の昨今ですので、新しい記事を投稿しました。
ディレクトリ形式で作成したい場合は引き続きこのページをご覧ください。
:::

https://qiita.com/Kanahiro/items/09abaa4ed80429b3ef28

## TL;DR

- GDAL v3.1で``gdal2tiles.py``に--xyzオプションが追加されたので、これを使えば簡単。以下コマンド例。

```sh
# source.tif -> target_dir の変換コマンド
# ズームレベル3-18で、XYZタイル形式で、4スレッドで並行処理するという意味
gdal2tiles.py source.tif target_dir -z3-18 --xyz --processes=4
```

- 元データは予め投影法をEPSG:3857にしておきましょう
- そうしなくても処理は出来ますが、事前に再投影しておいた方が圧倒的にタイル生成が速いです
- WindowsではQGISを使えば環境構築も簡単です

## 詳細

冒頭が結論です。以下には色々調べた結果のつらみが色々書いてあります

### つらみ①：gdal2tiles.pyは、--xyzオプションを付与しないとTMS形式のタイルが生成される

これが最大の罠で、現状、ネットを色々調べてもなかなかこれがわかりにくかった。TMS形式は、いわゆるXYZタイルとは南北が逆なので、日本国内のタイル作ってるのにオーストラリアにタイルが生成されてたりした。何やっても変な位置にタイルが作られるので半泣きだったが、ちゃんとドキュメントを読めば、``デフォルトはTMS``と書いてある。

https://gdal.org/programs/gdal2tiles.html

### つらみ②：--xyzオプションはGDAL3.1以降にしか存在しない

GDAL3.1は2020/1リリースです。比較的最近のリリースであり、つまりこれまではXYZタイル形式での変換はGDALでは出来なかったという事…（でも``ラスタータイル 生成``みたいに調べるとgdal2tiles.pyの情報が多数出てくる罠）。

> https://github.com/gsi-cyberjapan/gdal2xyztiles.py
ちなみに過去に国土地理院さんがgdal2tiles.pyを拡張したスクリプトを公開していたよう

### つらみ③：QGISのプロセッシングツールのgdal2tilesではXYZタイルをつくれない

> 2020-03-03: ①macOSのQGIS3.16でバージョン情報みたら3.1.2となっていました②Windows 64bitのQGIS3.18でバージョン情報見たら3.1.4になっていましたので、QGIS内蔵のGDAL自体のバージョンは問題なさそうです

QGISのプロセッシングツール経由のgdal2tilesではXYZタイルを作る事はできません。XYZタイルをつくる`XYZタイルの生成`というプロセッシングツールはありますが、こちらはQGISのキャンバスのレンダリング結果を用いるため、処理が非常に遅いです（QGISキャンバスを用いるゆえの便利さもあります）。

### つらみ④：GDALの環境構築

#### Windows

QGISにはGDALが内蔵されているので、それを利用するのが簡単です。QGISのPythonコンソールではGDALへのパスが通っているためsubprocessで動かせます。下記が例（QGIS3.16 LTRで検証）。

```python
import subprocess
subprocess.run("gdal2tiles.bat src.tif output_folder -z0-16 --xyz --processes=4 -w none", shell=True)
```

#### Ubuntu


``apt-get gdal-bin``で入りますが、これはバージョンが``2.4.2``になってNG。

https://qiita.com/ozo360/items/f78c95795827d7732dff にてUbuntuで最新のGDALをインストールする方法が紹介されています。

#### macOS

```sh
# GDALをbrewで最新にしてpython-bindingsも最新にすればよい
brew install gdal
pip install --upgrade gdal
```

#### Docker

これが一番簡単でしょう。-vと-wはホストマシンのカレントディレクトリをコンテナのカレントディレクトリとするイディオムです。

```sh
docker run -it -v $PWD:/usr/src/app -w /usr/src/app osgeo/gdal gdal2tiles.py src.tif output_folder -z0-16 --xyz --processes=4 -w none
```
最安値に挑戦！AWSとRTX1210の拠点間VPN接続

AWSで拠点間VPN接続をするのであれば、通常はマネージドサービス（AWSサイト間VPN接続）を使います。しかし、[0.048USD/hourの費用][2]、1か月(744時間)で35ドル強の費用が掛かり、個人で使うには厳しい金額です。
そこで、できるだけ安く拠点間VPNを行うための方法を模索し、定期的にQiitaに載せていたのですが、ようやく実現したのでこの記事でまとめておきます。

# 節約のポイント
- AWS側のVPNサーバとしてEC2を利用し、ソフトウェアはLinuxベースのstrongSwanを使用
- ~~EC2のインスタンスタイプは、現状AWSで最安値であるT4g.nanoを利用~~
 - リザーブドインスタンスが余っていたため、今回はt3.nanoで構築しています
- OSはminimalイメージを活用し、EBS 2GBで運用
- 自宅側の固定IP費用を削減するため、IPv6で接続

# 接続構成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/776880/8c2e071a-7f7c-7853-b727-526318aa4f35.png)
### AWS側
EC2にLinuxインスタンスを立て、strongSwanを利用してIPSecトンネルを張ります。T3に比べて20%OFFで利用できる、Arm系のT4gインスタンスを使う、、、予定だったのですが、t3.nanoのリザーブドインスタンスが手持ちに余っていたため、今回はそちらを利用しています。

###自宅側
VPNルータとしてYAMAHAのRTX1210を利用し、光回線はIPoE接続のフレッツ光コラボを利用します。固定IPは費用が掛かるため、半固定で付与されているIPv6アドレスを利用してVPNトンネルを張ります。IPv6アドレスが変更されることは滅多にないと予想されるため、その際は、再度一から設定をし直すこととします。

# strongSwanのインストール・設定
strongswanを設定する際は、strongswan5.8より推奨化されているswanctlを利用します。OSにubuntu 20.04 LTSを利用すると、strongSwan5.8系がインストールされ、swanctlも容易に利用できるのですが、**EBSで8GB課金されてしまうという問題**があります。
今回はできるだけ安く運用するという方針のもと、Amazon Linux 2のminimalインスタンスを利用し、EBS 2GBで運用します。(0.576USD≒約60円の節約)

strongSwanのインストール方法は以下の記事を参照してください。
[Amazon Linux 2 minimalイメージにstrongSwan5.9.1をインストール][1]

strongSwanとRTX1210間でIPSecトンネルを張るための設定方法は以下の記事を参照してください。
[strongSwanとRTX1210の拠点間VPN接続(IKEv2, IPv4 over IPv6)][3]

# 費用
通信費を除き、3.042 USD（約320円）になりました。なんと**91％OFF**です！T4g系を利用して3年分の利用契約をすればさらに安くなります！新規で購入するのであれば、リザーブドインスタンスよりもSaving Planを利用すると安いインスタンスタイプが出た際に容易に対応できるようになるかと思います。

- T3.nanoリザーブドインスタンス コンバーチブル3年間　2.85USD
- EBS 0.096USD/GB × 2(GB) = 0.192 USD

# 参考：過去に投稿したQiitaのリンク
- [LightsailでSecureNATを有効化したSoftEther VPN Serverを構築する][4]
 - 当初はSoftEther VPN Serverを利用しようと考えていました。通信料削減のためにLightsailを利用できないか検証しましたが、ルートテーブルがいじれないので VPNServer側でNATが必要なことに気づき、LightSailの利用は諦めました。
- [T4gインスタンスにIPv6を有効にしてSoftEther VPN Server を構築する][5]
 - SoftetherでL2TPv3を利用して接続する作戦でしたが、VPNトンネルは張れても、トンネルとブリッジ接続をしようとするとインターネットにつながらなくなったため諦めました。。。
- [strongSwanでIPv4 over IPv6のVPNトンネルを構成する][6]
 - SoftEtherは諦め、strongSwanに切り替え。strongSwanのインストールに手間取りましたが、strongSwan同士の検証は特にトラブルもなく利用できました。
- [strongSwanとRTX1210の拠点間VPN接続(IKEv2, IPv4 over IPv6)][3]
 - strongSwanとYAMAHAルータで検証。ちょっと設定変える必要がありましたが何とか接続成功。調べるときにIKEv1とIKEv2の情報が入り乱れていて、結局信用できるのは公式サイトの情報だと改めて感じた次第。
- [Amazon Linux 2 minimalイメージにstrongSwan5.9.1をインストール][1]
 - strongSwanの検証ではUbuntuを利用していたため、AmazonLinux2のminimalイメージに入れられないか検証。


[1]:https://qiita.com/kerorinfather/items/d05901dd7ba11ca84ee3
[2]:https://aws.amazon.com/jp/vpn/pricing/
[3]:https://qiita.com/kerorinfather/items/286b9647bdb7068b367d
[4]:https://qiita.com/kerorinfather/items/377267b3dcab6068200a
[5]:https://qiita.com/kerorinfather/items/4463f43ec554b4275a76
[6]:https://qiita.com/kerorinfather/items/37aec492f04706d55ade
PHP ログイン認証の作成手順②　〜新規登録機能作成とバリデーションの作成〜

#手順
##新規登録画面の作成
今回は、`ユーザ名`、`メールアドレス`、`パスワード`、`パスワード確認`の４つのフォームを用意する

```php:signup_form.php
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ユーザ登録画面</title>
</head>
<body>
    <h2>ユーザ登録フォーム</h2>
    <form action="register.php" method="POST">
    <p>
        <label for="username">ユーザ名：</label>
        <input type="text" name="username">
    </p>
    <p>
        <label for="email">メールアドレス：</label>
        <input type="email" name="email">
    </p>
    <p>
        <label for="password">パスワード：</label>
        <input type="password" name="password">
    </p>
    <p>
        <label for="password_conf">パスワード確認：</label>
        <input type="password" name="password_conf">
    </p>
    <p>
        <input type="submit" value="新規登録">
    </p>
    </form>
</body>
</html>
```

##新規登録完了画面の作成

```php:register.php
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ユーザ登録完了画面</title>
</head>
<body>
    <p>ユーザー登録が完了しました。</p>
    <a href="signup_form.php">戻る</a>
</body>
</html>
```

##バリデーションの作成
入力フォームにて入力し、送信した後はregister.phpへ情報が飛んで、リンクに繋がる。
その時にregister.phpの方で、登録が完了したか、入力エラーがあるかどうかを表示させる仕組みを作成する。
なお、新規登録を完了させることができた場合の処理はのちに行う。

①入力エラーが存在するフォームそれぞれに対して、エラーの文字を配列で集めていく。
②一つでもエラーの配列の要素がある場合は、あるもの全てをforeachで表示させていく。

```php:register.php

<?php
// エラーメッセージ
$err = [];

// バリデーション
if(!$username = filter_input(INPUT_POST, 'username')){
    $err[] = 'ユーザ名を記入してください';
}

if(!$email = filter_input(INPUT_POST, 'email')){
    $err[] = 'メールアドレスを記入してください';
}

$password = filter_input(INPUT_POST, 'password');
// 正規表現
if(!preg_match("/\A[a-z\d]{8,100}+\z/i", $password)){
    $err[] = 'パスワードは英数字８文字以上１００文字以下にしてください。';
}

$password_conf = filter_input(INPUT_POST, 'password_conf');
if($password !== $password_conf){
    $err[] = '確認用パスワードと異なっています';
}

if(count($err) === 0){
    //ユーザを登録する処理
}
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ユーザ登録完了画面</title>
</head>
<body>
<?php if (count($err) > 0) : ?>
<!-- エラーがある場合にforeachで該当エラーを表示させる -->
    <?php foreach($err as $e) : ?>
    <p><?php echo $e ?></p>
    <?php endforeach; ?>
<!-- $err配列に何もない＝エラーがない　から完了画面を表示させる -->
<?php else: ?>
    <p>ユーザー登録が完了しました。</p>
<?php endif ; ?>
<a href="signup_form.php">戻る</a>
</body>
</html>
```
リポジトリの複製（プロジェクトを別名で複製）する方法




#プロジェクトをコピーしてそれぞれ別物として運用したいときになど！

```

git clone --mirror git@github.com:a.git hoge
git clone --mirror 複製元のgithubのリポジトリurl 複製先のフォルダ名 


cd 複製先ローカルフォルダに入る


※※ githubで複製先のリモートリポジトリを新しく作っておく ※※


git remote set-url origin git@github.com:複製先.git


git push --mirror origin



```
Atcoder Beginner Contest 163 躓いたところまとめ

#Atcoderについて
AtCoder（アットコーダー）とは、「競技プログラミング」と呼ばれるコンピュータプログラムのコンテストを行うサービス、および高橋直大が代表を務めるその運営会社を指す。(Wikipediaより)
今回プログラミングの練習でいい機会と思い登録してみました。163回目のコンテストで躓いたところについてまとめていきます。

#環境
Windows10
python 3.8.2

#問題A

##円周率について

いつも忘れてしまうのが円周率。表記方法がいくつかあります。

###mathモジュールを使用する方法
```python:math
import math

print(math.pi)
```

###numpyを使用する方法
```python:nupy
import numpy as np

print(np.pi)
```
###mpmathを使用する方法
```python:mpmath
from mpmath import *

mp.dps = 10
print(pi)
```
Pythonのinput関数

#Pythonについて
Pythonは、汎用のプログラミング言語である。コードがシンプルで扱いやすく設計されており、C言語などに比べて、さまざまなプログラムを分かりやすく、少ないコード行数で書けるといった特徴がある。(Wikipediaより)
簡単に言うと有名で簡単なプログラミング言語です。

#Pythonのinput関数
ちょっと躓いたことのリマインドとしてinput関数を挙げておきます。
input関数は、terminal等にキーボードで打ち込んだ文字を認識するための関数です。

python2系

```python:python2
raw_input()
```

python3系

```python:python3
input()
```
【Instantiate関数】銃弾の向きが正しい状態で発射する【テンプレスクリプト】

## プレファブで弾を発射する
### 銃口(Muzzle)から弾(bullet)のクローンが発射される
- 下記Muzzle.csをMuzzleオブジェクト(銃口)へアタッチすることによって、プレファブ化されたbullet(弾)を発射することができます。

```Muzzle.cs
using UnityEngine;

public class Muzzle : MonoBehaviour
{
    public GameObject bullet;

    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Shot();
        }
    }

    void Shot()
    {
        GameObject obj;
        //====+====+====+====+====+====+====+====+====+====+====+====+====+====+
        //Instantiate関数の第二第三引数を設定することにより、通常の銃弾のような、
        //正しい向きが求められるbulletを生成することもできます。
        //====+====+====+====+====+====+====+====+====+====+====+====+====+====+
        obj = GameObject.Instantiate(bullet, transform.position, transform.rotation); 
        obj.GetComponent<Rigidbody>().AddForce(transform.forward * 1000);
    }
}
```