OmniAICreator/Qiita-1.07M huggingface dataset:
[CSS] opacity で困った

# opacity で困った！
- Vue.js + tailwind 環境
- ローディングのオーバーレイを CSS のプロパティ `opacity` で実装した。
- Firefox ではうまくレンダリングされたが、chrome で表示が崩れた。
- しかも２回目以降のローディング表示は正しく表示された。

### 1 回目 → 崩れる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474068/54785912-c44a-ba8e-71aa-97764c12843a.png)

### 2 回目 → 正しく表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474068/342a9566-5104-5030-10ac-1afb52a1ed5f.png)


# opacity vs rgba
opacity の挙動が怪しいと思ったので調べました。
 
### opacity
子要素の `text` や `background` の不透明度をすべて変更する

### rgba
スタイルを指定した要素のみに不透明度を設定する

### デモ
rgba を使用した `container` では、子要素に影響を与えないが、opacity を使用した `container-opacity` は子要素の `background` と `text` に不透明度が設定されている。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="popxqdp" data-user="punkshiraishi" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/punkshiraishi/pen/popxqdp">
  Untitled</a> by shiraishi yuma (<a href="https://codepen.io/punkshiraishi">@punkshiraishi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

# rgba に変更した結果
１回目から崩れずに表示されるようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474068/0b41a13a-84fd-bace-4cea-fe0b0e253ddc.png)

# 仮説
`opacity` 属性による指定では、より多くの要素をレンダリングすることになる。Vue による DOM の生成のタイミングなどの条件と重なり、表示崩れを起こしてしまった。

一方 rgba では単一の要素にしか影響を与えないので、レンダリング処理がシンプルになり、問題が解消したのではないか。

# tailwind を使う場合
### opacity-xx
`opacity: xx;` を付与します。

### bg-opacity / text-opacity / border-opacity
rgba で不透明度を指定します。

`bg-red-500` は下記のようなスタイルが付与されます。

```css
.bg-red-500 {
    --tw-bg-opacity: 1;
    background-color: rgba(185,28,28,var(--tw-bg-opacity));
}
```

`--tw-bg-opacity` は変数で、`bg-opacity` によって指定できます。
```css
.bg-opacity-50 {
  --tw-bg-opacity: 0.5;
}
```

# 結論
opacity は影響範囲を理解して使いましょう。
特定の要素の不透明度を変えたいときはなるべく `rgba` を使った方が良さそうです。


# 参考
https://tailwindcss.com/docs/background-color#changing-the-opacity

https://stackoverflow.com/questions/13385492/css-opacity-vs-rgba-which-one-is-better
GAE / Cloud Functions + Datastore + Goで“rpc error: code = PermissionDenied desc = Missing or insufficient permissions.” エラー

今回は特殊な要件で作業していたので、珍しいエラーを引きました。０から構築した場合は発生しないのでケースは多くないと思いますがメモとして残しておきます。


# 概要
GAEとDatastoreを利用したGoのサンプルプログラムがありました。これをバージョンアップ・修正しデプロイしようとしたところ、表題のエラーになりました。

```
$ gcloud app deploy --project {プロジェクトID} --version {バージョン} .
...
（デプロイは成功する）
```
デプロイしたプログラムの動作確認のためにブラウザからアクセスすると、下記のエラーメッセージが表示されます。

`rpc error: code = PermissionDenied desc = Missing or insufficient permissions.`
権限不足というエラーメッセージと、下記のstackoverflowのポストを見て、なにかしらの権限が不足しているのではないかと思い調べましたが、違うところに原因がありました。
https://stackoverflow.com/questions/61651865/getting-error-message-rpc-error-code-permissiondenied-desc-missing-or-ins

# 原因と対処法
サンプルプログラムの中にGCPのプロジェクトIDがハードコードされており、別のプロジェクトにデプロイしようとしたところエラーが発生していたことがわかりました。ハードコードされた部分を修正し、今回のデプロイ対象のプロジェクトIDを指定することでエラーが解消されました。

また、デプロイ対象と異なるプロジェクトIDをプログラム内で指定すると、同じエラーがGoogle CloudFunctionsでも発生しました。

プログラムの中にプロジェクトIDをハードコードしていると、今回のような場合に気づくのが難しいため、環境変数からプロジェクトIDを読みこむようにプログラムを修正するのが望ましいです。GAEの場合、　`GOOGLE_CLOUD_PROJECT` という環境変数に実行環境のGCP プロジェクトIDが入るので、プログラム内でプロジェクトIDを直接指定するのではなく、os.Getenv("GOOGLE_CLOUD_PROJECT")のような形でプロジェクトIDを読むようにします。
https://cloud.google.com/appengine/docs/standard/go/runtime#environment_variables
DynamoDBのキー・インデックスを整理する


## はじめに
DynamoDBを仕事で扱っているが、キーやインデックスに関して理解が浅いため、改めて整理する

## キー

### プライマリキー
- プライマリキーによってデータを一意に識別できる
- 以下の2つのパターンが存在する

#### パーティションキー
- プライマリキー = パーティションキーのパターン
- パーティションキーが重複する項目を作成できない

#### 複合プライマリキー
- プライマリキー = パーティションキー + ソートキー
- これらの2つのキーが重複する項目を作成できない

## セカンダリインデックス
- パーティションキー・ソートキーだけでは不十分な場合、別途パーティションキー・ソートキーを設定することができる
- 以下の2種類存在する

### グローバルセカンダリインデックス
- パーティションキーとソートキーをプライマリキーとは別でもつ

#### 具体例

- 以下のテーブルがあるとする
- プライマリキー
    - パーティションキー：UserId
    - ソートキー：GameTitle

![GSI_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/882682/cd2c53b1-8196-0b34-c460-a7510aa5065f.png)

- UserIdやGameTitleを指定したクエリは効率的に可能
- しかし、例えば、TopScoreを指定したクエリは効率的にできない
    - Scanで全てのデータをクエリする必要があり、効率が悪い
- この場合、以下のグローバルセカンダリインデックスを作成する
    - パーティションキー：GameTitle
    - ソートキー： TopScore
    - ベーステーブルのプライマリキー属性は必ずインデックスに射影されるので、UserId 属性も存在する
- 結果として、以下のインデックスを作成でき、TopScoreに関連したクエリを効率的に実行できる

![GSI_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/882682/777a30d8-2779-fcd3-6de1-9bc1cda39bc7.png)

### ローカルセカンダリインデックス
- パーティションキーはベーステーブルと同じで、ソートキーを別でもつ

#### 具体例

- 以下のThreadテーブルがあるとする
- プライマリキー
    - パーティションキー: ForumName
    - ソートキー: Subject

![LSI_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/882682/ddc96c6d-ff3a-2367-6975-0ff8b169686a.png)

- 上記以外のキーでなにかしら絞り込みたい場合、Scanで全データをクエリする必要があり、効率が悪い
    - 例えば、特定のフォーラムに過去3か月以内に投稿されたすべてのスレッドを検索する場合、ローカルセカンダリインデックスがないとテーブル全体に対してScanクエリを実行して、指定された時間枠から外れた投稿を破棄する必要がある
    - ローカルセカンダリインデックスがあればQueryオペレーションでLastPostDateTimeをソートキーとして使用して、効率的にデータを取得できる
- そこで、以下のローカルセカンダリインデックスを作成する
    - パーティションキー: ForumName
    - ソートキー: LastPostDateTime
    - ベーステーブルのソートキー(Subject)がインデックスに射影され、非キー属性として機能する

![LSI_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/882682/26035b9e-6817-215d-f92f-d6eb6b33a6c3.png)


## 参考
- https://aws.amazon.com/jp/premiumsupport/knowledge-center/primary-key-dynamodb-table/
- https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/GSI.html
- https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/LSI.html
AWS公式資料で挑むSCS認定(40)-こんな時どうする(全分野その17)

##### [前回] [AWS公式資料で挑むSCS認定(39)-こんな時どうする(全分野その16)](https://qiita.com/mingchun_zhao/items/11956c3652a311ab0d2e)

## はじめに

SCS認定にめでたく合格した同僚からの体験談共有です、ありがたい。
[AWS Certified Security - Specialty合格しました！](https://qiita.com/kosuke_doi/items/909df7a3ebce221cf0bb)

今回も引き続き、「こんな時どうする」集の作成です。

## 分野1: インシデント対応

- 不正アクセスの疑いがある操作が報告された、過去同じ操作が行われていないか調査したい
    - 過去90日間のイベント履歴調査
        - CloudTrailコンソールのイベント履歴から、問題操作のAPIコールを確認
    - 過去90日間より前のイベント履歴調査
        - CloudTrailの証跡を作成し、収集イベントをS3バケットへ配信する必要あり

## 分野2: ログとモニタリング(監視)

- EC2インスタンスのセキュリティグループが不意に変更されていないか監視したい
    - Amazon EventBridgeとAmazon Simple Notification Service(Amazon SNS)を使用
        - Amazon SNSで、セキュリティグループ変更関連ルールに一致するイベントについて通知設定
            - トピックを作成
            - トピックARNを指定し、サブスクリプションを作成
        - セキュリティグループ変更に必要なAPIコールをトリガーとするEventBridgeルールを作成
            - ルールを作成し、イベントタイプで「CloudTrail経由のAWS APIコール」を選択
            - 特定オペレーションに、セキュリティグループルールを追加/削除する下記APIコールを指定
                - AuthorizeSecurityGroupIngress
                - AuthorizeSecurityGroupEgress
                - RevokeSecurityGroupIngress
                - RevokeSecurityGroupEgress
            - ターゲットとして、SNSトピックを選択

## 分野3: インフラストラクチャのセキュリティ

- ストレージ料金削減のためS3バケットデータを定期的に削除したい
    - オブジェクトの現行バージョンを失効させ、オブジェクトの以前のバージョンを完全に削除するライフサイクル設定ルールを作成
    - S3は毎日1回ライフサイクルルールを実行、S3が初めてルールを実行すると、有効期限切れに該当するすべてのオブジェクトに削除マーカーが付けられる
    - 削除対象としてマークされたオブジェクトに対する料金は請求されなくなる
    - ただし、ルールが実行されてバケットが空になるまで数日かかる場合あり
        - オブジェクトバージョンを失効させることと、削除マーカーをクリーンアップすることが非同期ステップであるため

## 分野4: アイデンティティ(ID)及びアクセス管理

- 別のAWSアカウントによりアップロードされたS3バケットオブジェクトにアクセスできない
    - デフォルトのオブジェクト所有権が設定された既存S3バケットの場合、オブジェクト所有者はオブジェクトをバケットにアップロードしたAWSアカウントとなる
        - `オブジェクト所有者`が、オブジェクトにアクセス許可を明確に付与しないと、`バケット所有者`はオブジェクトにアクセスできなくなる
    - 解決策として、`S3 Object Ownerships`を使用することで、バケット所有者は自分のバケットにアップロードされたオブジェクトの所有権を管理できるようになる
        - デフォルトで、新しく作成されたすべてのS3バケットでは、`bucket owner enforced`設定が有効になる
        - `bucket owner enforced`が有効になっている場合
            - バケット所有者はバケット内のすべてのオブジェクトのオブジェクト所有者になる
            - バケットとそのオブジェクトのACLはすべて無効になる
        - `bucket owner enforced`設定または`bucket owner preferred`設定を有効にすることで、既存のバケットに`S3 Object Ownership`を設定することもできる
            - `bucket owner preferred`設定が有効になっても、ACLは引き続き有効
        - `bucket-owner-full-control`ACLを使用し、バケットにアップロードされたオブジェクトだけが、バケット所有者によって所有される
        - `bucket owner enforced`設定が有効になっている既存のバケットで、`bucket owner enforced`設定を無効にすると、以前適用されていたバケットとオブジェクトACLが再度有効になる

## 分野5: データ保護

- AWS KMSキーにインポートされたキーマテリアルが誤って削除されたので復旧したい
    - 最初にKMSキーにインポートされたものと同じキーマテリアルを再インポートする必要あり
    - キーマテリアルの再インポート方法は、以下を除いては最初のキーマテリアルインポートと同じ手順
        - 新しいKMSキーを作成する代わりに、既存のKMSキーを使用
        - KMSキーにキーマテリアルが含まれている場合、キーマテリアルを再インポートする前に、既存のキーマテリアルを削除
        - KMSキーにキーマテリアルをインポートするたびに、KMSキーの新しいラップキーおよびインポートトークンをダウンロードして使用する必要あり
            - ラップ手順は、キーマテリアルの内容には影響しない、異なるラップキー(および異なるインポートトークン)を使用し同じキーマテリアルをインポート可能

## おわりに

「こんな時どうする」の追記でした。
次回も続きます、お楽しみに。

##### [次回] [AWS公式資料で挑むSCS認定(41)-こんな時どうする(全分野その18)](https://qiita.com/mingchun_zhao/items/935141b158b168931d80)
staticメソッドで非staticなDIオブジェクトを使いたい

# はじめに
staticメソッド内でmybatis用のmapper interfaceを@Autowiredして使いたかった時の話。
もちろんそのままだとstaticメソッドから非staticメソッドの参照だしそもそもinterfaceだしで使うことは出来ないので、回避策が必要。

# NGパターン
```MyMapper.java
package com.my.mapper;

public interface PhoneInfoMapper {
  int selectByHogeHuga(String hogeFuga);
}
```
```MyMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.my.mapper.MyMapper">
    <delete id="selectByHogeHuga" parameterType="java.lang.String" resultType="java.lang.String">
        select count(*) from my_table where hoge_huga = #{hogeHuga,jdbcType=VARCHAR}
    </delete>
</mapper>
```
```MyClassService.java
package com.my.service;
import com.my.mapper;

@Service
public class MyClassService {
  // 非static参照となるためコンパイルエラー
  @Autowired
  private MyMapper myMapper;

 // 実態はnullなので実行時エラー
  @Autowired
  private static MyMapper myMapper;

  public static void myMethod() {
    String hogeHuga = "hoge huga";
    String result = myMapper.selectByHogeHuga(hogeFuga);
  }
```

# OKパターン
```MyClassService.java
package com.my.service;
import com.my.mapper;

@Service
public class MyClassService {
  // static変数を用意
  private static PhoneInfoMapper phoneInfoMapper;

  // Spring Bootの起動時にsetter injectionでstatic変数にDI
  @Autowired
  private void setPhoneInfoMapper(PhoneInfoMapper phoneInfoMapper){
    FirebaseCloudMessagingConfig.phoneInfoMapper = phoneInfoMapper;
  }

  public static void myMethod() {
    String hogeHuga = "hoge huga";
    String result = myMapper.selectByHogeHuga(hogeFuga);
  }
```

# 参考リンク
* [staticメソッド内でDIを利用してみた](https://www.purin-it.com/di-in-static-method)
* [Spring FrameworkでDIする3つの方法](https://reasonable-code.com/spring-injection-method/)
aws lightsail snpashot (バックアップ)

# スナップショットを作成しよう

スナップショットとは、バックアップのこと。

>スナップショットを作成する時は、インスタンスを停止することが推奨

そのままの状態で作成すると復元時にバグる可能性があるから。

# スナップショットを作成

・サーバーを停止
「・・・」をクリックしStopでサーバーを停止。
サーバーをクリックし、Snapshotsの項目をクリック、
+Create snapshotをクリックして作成する。

管理画面から作成できる。
サーバーを再起動するときは、lightsailの管理画面から行う。

# スナップショットの復元

取得したsnapshotsをクリック。
右側の「・・・」をクリックしてcreatenewinstaceをやる。
とっても簡単。
GPUパススルーのLinuxのVMを作る

## 環境
```
Rocky Linux 8.5
RTX 2080ti x2枚
AMD EPYC 7352 x2
memory:128GB
```
それぞれ1枚ずつのVMを作って開発端末とする。

## VMの作成
```bash
sudo virt-install \
--name gpu3 \
--ram 8000 \
--disk path=/var/kvm/images/gpu3,size=20 \
--vcpus 4 \
--cpu host\
--os-variant centos8 \
--network bridge=br0 \
--graphics none \
--console pty,target_type=serial \
--location /tmp/Rocky-8.5-x86_64-minimal.iso \
--extra-args 'console=ttyS0,115200n8 serial' \
--host-device 01:00.0 \
--host-device 01:00.1 \
--host-device 01:00.2 \
--host-device 01:00.3 \
--features kvm_hidden=on \
--machine q35 \
--boot uefi,nvram_template=/usr/share/OVMF/OVMF_VARS.fd
```

## ポイント
すべてのPCIeデバイスを追加すること
UEFIブートが必須で、かつSecure bootは無効化すること。（ドライバが入らない）
kvm hiddenはonにしておく。
cpuのタイプも隠しておく。hostにしておく。
あらかじめブリッジを作成しておく。bridge filterも通す。

## VM上での作業
通常通りにインストールをし、nvidia-driverを入れる.

```bash
sudo yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm -y
dnf install wget kernel-devel gcc make dkms
cd /tmp/
wget https://jp.download.nvidia.com/XFree86/Linux-x86_64/510.60.02/NVIDIA-Linux-x86_64-510.60.02.run
chmod +x NVIDIA-Linux-x86_64-510.60.02.run
./NVIDIA-Linux-x86_64-510.60.02.run -dkms
```
CodeIgniter4 の $this->validate() でラベル付きのエラーメッセージを使用する

[公式ドキュメント](https://codeigniter4.github.io/userguide/libraries/validation.html)に記法が示されていなかったので。


# 確認環境
- CodeIgniter4 v4.1.9
- PHP 8.1.4

# 対応方法
Controller クラスの `validate()` メソッドでラベル付きのエラーメッセージを使用する場合は以下。


```diff_php:UserController
public function create()
{
    $input = $this->validate([
-       'name'     => 'required|max_length[100]',
-       'email'    => 'required|valid_email|is_unique[users.email]',
-       'password' => 'required|min_length[8]'
+       'name'     => ['label' => 'ユーザー名', 'rules' => 'required|max_length[100]'],
+       'email'    => ['label' => 'メールアドレス', 'rules' => 'required|valid_email|is_unique[users.email]'],
+       'password' => ['label' => 'パスワード', 'rules' => 'required|min_length[8]']
    ]);

    if (!$input) {
        return view('users/create', [
            'validation' => $this->validator
        ]);
    }
    // ...
}
```

**変更前**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243093/5c02fb25-1fb8-6f1b-41df-14ed61fa2129.png)

**変更後**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243093/dc2675d7-0a31-9037-eca0-badb2f15742c.png)

# 補足
公式ドキュメントより
> The validate() method is a method in the Controller. It uses the Validation class inside. See Validating data in Controllers.

結局、Validation クラス の `setRules()` メソッドが呼び出されているだけである。

```php:/vendor/codeigniter4/framework/system/Controller.php
protected function validate($rules, array $messages = []): bool
{
    $this->validator = Services::validation();

    // If you replace the $rules array with the name of the group
    if (is_string($rules)) {
        $validation = config('Validation');

        // If the rule wasn't found in the \Config\Validation, we
        // should throw an exception so the developer can find it.
        if (! isset($validation->{$rules})) {
            throw ValidationException::forRuleNotFound($rules);
        }

        // If no error message is defined, use the error message in the Config\Validation file
        if (! $messages) {
            $errorName = $rules . '_errors';
            $messages  = $validation->{$errorName} ?? [];
        }

        $rules = $validation->{$rules};
    }

    return $this->validator->withRequest($this->request)->setRules($rules, $messages)->run();
}
```
MMDETECTIONをgoogle colabolatoryで使うサンプルコード集


# はじめに

MMDETECTIONは、日本語の資料が少なく、基本的にはPCローカル環境での使用が前提となっているため、直接コンフィグファイルの書き換えを行わなければならなかったりといった制約があります。

使うモデルによって、コンフィグファイルの中身が違うため、コンフィグファイルの内容を確認しないとなかなか複数のモデルの比較ができないといった不便さがあります。

## MMDETECTIONのgoogle colabolatory用サンプルコード

MMDetectionを利用したサンプルコードを以下においておきます。
基本的にコンフィグを直接触ることなしで、学習、結果確認、大量のデータ予測までを実施できます。

https://github.com/saotomryo/Use_MMDetection


コンペなどで色々モデルを試してみたら、追加していこうと思います。

## サンプル掲載のモデル

2022年4月現在で掲載したモデル

 - yolov3  
 - yolox
 - htc_without_semantic
 - retinanet_swin
 -
エラーMSB3644：フレームワーク ".NETFramework、Version = v4.7"の参照アセンブリが見つかりませんでした

エラー原因：4.7のフレームワークがインストールしていない。

ここをクリックすると直接ダウンロード
https://dotnet.microsoft.com/ja-jp/download/dotnet-framework/thank-you/net47-web-installer
一からのやり方はここ：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2217957/c6d75722-28ad-98b8-7b84-0da06bb8d76b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2217957/176bfa73-db73-f682-cb7a-46f515a049e3.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2217957/05c94971-8354-8d58-5f11-5636b48876bf.png)

以上です。
数学における0の意味

『プログラマの数学』という本の第一章を読んで、そのアウトプットをしてみようと思います。
今回はそんなに長くならない気がするので、ぜひ最後までお付き合いいただきたいです。

## 数学における0の役割
0というのは、**何もないことを表すための数字**であるというが、0の役割です。
例えば、```2022```という数字があるとします。
一の位が2、十の位が2、百の位が0、千の位は2ですね。
百の位の0は百の位がないことを表しています。
だからといって、0を取ってしまって```222```と書いてしまうと違う数字になってしまいます。
だから、何もないことを表すための数字として存在する0を使って```2022```を表しているんですね。

これがすごいことなんですね。
代表的な数字の表し方として、ローマ数字があります。
気になる方は調べていただきたいのですが、ローマ数字は足し算ならギリ何とかなるんですが、引き算掛け算になるとお手上げなんですね。

しかし、0をつかった10進法で計算すると、簡単に計算ができるんです。

以上です。何か間違いがございましたら、ご教示いただけますと幸いです。

【参考文献】

https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%81%AE%E6%95%B0%E5%AD%A6%E7%AC%AC2%E7%89%88-%E7%B5%90%E5%9F%8E-%E6%B5%A9/dp/4797395451
無料版データウェアハウス　Vertica Communitiy Editionを構築 VMWare編


Vertica Analytics Platform（以降、Vertica）のCommunity Editionを使い、データ分析を実施するためのテスト環境をEnterprise Modeで構築することを目的としております。
Community Editionとは、3ノードクラスター、データサイズ1TBまで無料でお試しいただけるエディションとなります。商用でも利用できますが、テクニカルサポートは利用できない制約があります。

1) Vertica Community Editionのダウンロード
2) Vertica Community Editionの起動
3) データベースの作成と削除
4) データベースの起動と停止
5) データベースオブジェクトの作成
6) データロードとクエリ
7) データベースデザイナーの実行

*******
クエリの例はこちらです。

```sql:hello.sql
create table customer_dimension
(	customer_key            integer         not null primary key,
	customer_type           varchar(16),
	customer_name           varchar(256),
	customer_gender         varchar(8),
	title                   varchar(8),
	household_id            integer,
        customer_address        varchar(256),
	customer_city           varchar(64),
	customer_state          char(2),
	customer_region         varchar(64),
	marital_status          varchar(32),
	customer_age            integer,
	number_of_children      integer,
	annual_income           integer,
	occupation              varchar(64),
	largest_bill_amount     integer,
	store_membership_card   integer,
	customer_since          date,
	deal_stage              varchar(32),
	deal_size               integer,
	last_deal_update        date
);

```

システム構成は以下の図のようになる。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635373/d44d9c0c-cc29-3e6a-8ddd-ea3b47fc839b.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635373/0ba2790f-0465-37f2-4182-a13746444367.png)
	導入環境	テスト環境
VirtualBoxでYou must specify a machine to start, using the command line.と言われたときの対処法

# はじめに

Mac環境での対処方法です。

## VMを強制終了したらエラーが出た

`You must specify a machine to start, using the command line.`というエラーが出ました。

![スクリーンショット 2022-04-15 13.18.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169789/5c472ba6-8138-4785-cfa4-9ad0119b85bb.png)

```
You must specify a machine to start, using the command line.

Usage: VirtualBoxVM --startvm &lt;name|UUID&gt;
Starts the VirtualBox virtual machine with the given name or unique identifier (UUID).
```

## 対処法

### コマンドでVMの一覧を表示

```sh
VBoxManage list vms
```

こんな感じに名前が出ます。

```sh
❯ VBoxManage list vms

"english-version" {d6518xxx1c7-xx-47xx37-a64f-xxxxx}
```

### 名前を指定して起動

```sh
VirtualBoxVM --startvm english-version
```
webサーバで実装する機能の案

# 前提

自分のポートフォリオを作成してサーバ上に構築したい。この記事では、自分がwebサーバ実装したい案について記す。

# ポートフォリオ案のリスト

1. ゲームを作成してwebサーバ上に構築
1. Webサービスの作成


# 1の案についての詳細

ゲームを作成してwebサーバに構築する場合の疑問点について記す。

### 疑問点

1. どのようなゲームを作成するか?
    - 軽量な2Dのゲームかそれとも3Dゲームか?
        - 3Dゲームの場合webサーバの容量は足りるのか？
    - 作成するゲームの構想は?

1. 使用する言語について
    - pythonを使用する場合
        - 今学習しているDjangoを用いてゲームを作成することができるか?
        - もしくは他のpythonのフレームワークと併用するか?
    - C++を使用する場合
        - webサーバ上にアップロードすることができるのか？
        - アップロードできる場合どのような形でアップロードするのか？
    - Unity(C#)を使用する場合
        - webサーバ上にどのようにアップロードするのか？

以上の点について検討する。検討した場合は再度記事を作成する。

# 2の案についての詳細

どのようなWebサービスを作成したいかについてはまだ決めていない。よって、Webサービスを作成してポートフォリオを制作する場合の疑問点と作成したいwebサービスについて記す。
作成する場合はDjangoがメインになると思う。

### webサービスの案リスト

1. 仮想通貨の情報アプリ
   - どのようなものを作りたいか深く考えていない
1. 2chや5chみたいな掲示板
   - 掲示板のUIはTwitterやyoutubeみたいに綺麗にしたい。
   - Twitterの便利な機能とYouTubeの便利な機能を合わせい。
1. 自分のブログ
   - 簡単に作れるためすぐできそう

<br>

他にも作成したい案があれば記載する。

### 疑問点

疑問点は今の所なし

# まとめ

以上に記した案について深く検討する。深く検討したことについてはこの記事に追記するか新しい記事を作成する。
Ajaxで画像やファイルなどを送信するときに、以下のように注意！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509696/7caee782-fb3e-f5ce-32a9-332734fd2d3d.png)
※processData: falseとcontentType: falseがポイントのようです。
Jupyter NotebookでなくJupyter Labを起動する方法

Windows環境でAnacondaをインストールしてJupyterを使おうとしたらJupyter NotebookとJupyter Labがあることに気づいた。
スタートメニューから起動するとJupyter Notebookが起動するが、新しいのはJupyter Labらしいので設定を変更してJupyter Labが起動するように変更した。

1. Anaconda Promptを開いて設定ファイルを生成。
    ```python
    jupyter notebook --generate-config
    ```
2. `C:\Users\ユーザ名\.jupyter\jupyter_notebook_config.py`が作られているので開く。
3. 下記のところを`lab`に書き換える。
    ```python
    c.NotebookApp.default_url = '/lab'
    ```

設定ファイルは.pyなので行頭に余計なスペースなどが入るとエラーで設定が有効にならない。

追記。。
Jupyter LabはWindowsでAnacondaをインストールした環境で確認しました。純粋にJupyter Notebookをインストールした場合などはその限りではありません(404になりました)。
Vuetifyのv-data-table v-simple-tableで改行を行う方法

# はじめに
Vuetifyの`v-data-table`や`v-simple-table`を使用すると、簡単にリッチなテーブルを作成することができます。
https://vuetifyjs.com/ja/components/data-tables/

テーブル内のデータの改行を行いたかったため調べてみました。

# 実装方法

改行を行いたい箇所に`\r\n`を入れます。
```vue
        <v-simple-table dense>
          <template v-slot:default>
            <thead>
              <tr>
                <th class="text-left">
                  項目名
                </th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td>{{ value }}</td>
              </tr>
            </tbody>
          </template>
        </v-simple-table>

～省略～

  data() {
    return {
      value: '1行目\r\n2行目'
    }
  }
```

このままでは下記画像の通り改行されません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2347087/638c99e5-fb2f-910f-4964-d779ffa305ac.png)

styleに`white-space: pre-wrap;`を設定することで改行できました。
scopedなのでこのファイル内のみ改行されることになります。

```vuejs
<style scoped>
.v-data-table >>> td {
  white-space: pre-wrap;
}
</style>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2347087/1f20a816-bb28-2fc8-b1bc-aee01de729f2.png)
【Java】正規表現で最後にマッチした文字列のみを置換する方法

正規表現で最初にマッチした文字列のみを置換する方法としてreplaceFirstメソッドが存在するが、最後にマッチした文字列のみを置換するreplaceLastメソッドはない。
探してみたところ、replaceFirstを応用して自作している人がいた為、使わせていただいた。

```java:replace.java
public static void main(String[] args) throws Exception {
 
    String str = "hoge 0123 PIYO 4567 hoge 890 FUGA";
 
    // 小文字アルファベットの1回以上の繰り返しを""abc""に置換
    String result1 = replaceLast(str, "[a-z]+", "abc");
 
    System.out.println( result1 ); // hoge 0123 PIYO 4567 abc 890 FUGA
}
 
public static String replaceLast(String str, String regex, String replacement) {
    if(str == null || str.isEmpty()){
        return str;
    }
    
    return str.replaceFirst(regex+"(?!.*?"+regex+")", replacement);
}
```

否定先読みでregexを指定することで最後にマッチした文字列のみを置換するようにしているっぽい。
正規表現できる人すごい...
GitHubにSSH接続するための設定方法

## はじめに

GitHubのSSH接続するための設定方法を紹介している記事は多いです。
しかし記事によって、設定の仕方が微妙に違っていて慣れていない人は混乱し易いと感じため、自分なりにまとめました。
また、リモートとの push 、pull 操作の際のSSH接続で毎回パスワードを聞かれないようにする設定も紹介します。

## SSH接続の設定が必要な理由

GitHubでは2021年8月13日からパスワード認証が廃止されているため、リモートに push や pull 操作などをしたい場合はSSHやPersonal access tokenを利用する必要があります。
https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/

## SSH接続するための設定

### 1. 公開鍵、秘密鍵の作成

最初に鍵を保存する ~/.ssh ディレクトリに移動する。
```
cd ~/.ssh
```

以下のコマンドで公開鍵と秘密鍵を作成します。
暗号化方式は ed25519 にします。
```bash
$ ssh-keygen -t ed25519 -f github
```

パスフレーズを聞かれたら入力します。
これで完成です。
github：秘密鍵
github.pub：公開鍵

### 2. GitHubに公開鍵を登録

GitHubの Setting にある SSH and GPG keys に移動し、New SSH Key から公開鍵を登録します。
Title：自由に決めます。
Key：github.pub の中身をコピペします。

### 3. 設定ファイルを作成

~/.ssh/config に以下を記載する。
~/.ssh/config が存在しなかったら作成してください。
```:~/.ssh/config
Host github github.com
  HostName github.com
  IdentityFile ~/.ssh/github
  User git
```

### 4. key-agentに登録

これをしておくと、パスワードを毎回聞かれないようになります。
パスフレーズを聞かれたら入力します。
```bash
$ ssh-add ~/.ssh/github
```

### 5. 接続を確認

以下のコマンドでGitHubにSSH接続します。
```
$ ssh -T github.com
```

以下のように返ってきたら成功です。
```
Hi ユーザー名! You've successfully authenticated, but GitHub does not provide shell access.
```

## パスワードを聞かれないための設定

key-agentに登録しておくと、パスワードを毎回聞かれないようになります。
mac の場合は、システムアップデートした後にSSH接続をしようとするとパスワードが聞かれるようになる時がありますが、key-agentに再び登録するとパスワードを毎回聞かれないようになります。

## 最後に

最後まで目を通していただき、ありがとうございます。
GitHubにSSH接続するための設定をする際の参考になれば幸いです。
Apacheが起動できなくなった

数か月ぶりにxamppを起動しようとしたらApacheが起動できなくなった。
簡易パネルのエラー文言を読む。
```
11:15:15  [Apache] 	This may be due to a blocked port, missing dependencies, 
11:15:15  [Apache] 	improper privileges, a crash, or a shutdown by another method.
11:15:15  [Apache] 	Press the Logs button to view error logs and check
11:15:15  [Apache] 	the Windows Event Viewer for more clues
11:15:15  [Apache] 	If you need more help, copy and post this
11:15:15  [Apache] 	entire log window on the forums
```
簡易パネルの文言なのでポート番号が重複してるのか、必要ファイルが消えてるのか、権限がないのか、確実な原因が分からない。
そこでエラーログ見てみたけどなぜか数か月前のログしか出てない。
検索して見つけた記事でhttpd.confやhttpd-ssl.confやhttp-vhosts.confの記述（ServerNameまわりなど）をちまちま変えて再起動を試みるが同じエラーが出る（元に戻す）。
そもそも今まで問題なく動いていたのになんで動かなくなる。
この間gulpでポートの設定をしたけど今そちらは起動していないし影響はないはず……
分からなくてこの件をポロッとMTGでこぼしたら先輩エンジニアに「IISの影響では？」と助言をもらった。それだ。
https://shimonss.hatenablog.com/entry/2016/09/04/201518
IISを停止したら問題なく起動できました。
自分で気づけなくてくやしッ。

### 追記
「スタートアップの種類」を自動のままにしておくとシャットダウン後PCを立ち上げた時にまた自動で実行されてしまう。常時IISを使うわけでもないなら「手動」に変えておく。

### さらに追記
今度はmysqlが起動しなくなり、下記記事参考に復旧しようとしたが、wordpress復旧のあたりでめちゃめちゃになったのでwordpressと関連DBに関しては再設定となった。くやしい。

https://y-a-d.hatenablog.jp/entry/2020/01/28/183000
文字化けを起こさない

# はじめに
WindowsのコマンドプロンプトやPowerShellはデフォルトのコードページがCP932であることが多いです。
このせいでWindows環境ではVS Codeのせいではありませんが、VS Codeのターミナルで文字化けが起こります。

2022/10/09 追記: Windows 11のPowershellでchcp 65001を実行しても文字化けが起こる事象を確認しています。対処法は現在調査中です。
2022/04/19 追記: より簡単なワンライナーの対処法を追加しました。

# 対処法１

以下のコマンドレットをVS Codeのターミナル上で実行します。

``` powershell
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser; ni $profile -force; echo "chcp 65001 > $null" > $profile
```

警告が表示されますが`y`を入力します。

## なぜなのか

`$profile`に格納されているパスでスクリプトファイルを作成し、コードページをCP65001に変更するコマンドレットを書き込んでいます。
`$profile`のスクリプトはPowerShellの起動時に実行されます。
PowerShellの起動時にコードページをCP65001に変更することによって、UTF-8で出力されても文字化けしなくなるわけです。

しかし、PowerShellスクリプトを実行させるために実行ポリシーを変更しています。
ローカルで作成されたスクリプトは実行できるようになってしまうので、セキュリティ上のリスクが生じます。
このリスクを回避するには次の対処法を使ってください。

# 対処法２

**上記の対処法を行っている場合、こちらを行う必要はありません。**

`settings.json`に以下を追加します。

``` json
"terminal.integrated.profiles.windows": {
    "PowerShell": {
        "source": "PowerShell",
        "icon": "terminal-powershell",
        "args": [
            "-NoExit",
			"chcp",
			"65001",
            ">",
            "$null",
        ]
    },
},
```

ファイルの先頭から始まる大きな{}の中に入れます。

## `settings.json`の開き方

`Ctrl + ,`のショートカットを使うか、

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/953829/d609219b-48b9-8257-e609-6b14d38e5b79.png)
左下の歯車マークを押し、
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/953829/31918f7e-206b-664b-8028-fac28da3265d.png)

設定を開きます。

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/953829/a9618e76-185e-e3ac-9642-1eb22fc91432.png)
右上のファイルアイコンを押します。

## なぜなのか

これによってPowerShell起動時にコードページがCP65001に変更されます。
UTF-8で出力されても文字化けしなくなるわけです。
PowerShell以外に適用する場合はさらに設定を編集する必要があります。
Ruby を書き始めてハマったこと


## `String` なのか `Symbol` なのか

Ruby には `Symbol` という、文字列の皮を被った数値があり、少メモリで高速なことから、`Hash` のキーとかでよく見かけます。

自分で作った `Hash` であれば誤解はないですが、メソッドから生成された `Hash` のキーが `String` だったりすると、キーを指定しても `nil` が返ってきて、「俺が入れたデータが無くなっとる！」と焦ります。

### `JSON.parse` は `symbolize_names: true` をつけると `Symbol`

`JSON.parse` でそのままだと、キーは `String` になる。

```ruby
JSON.parse('{"name":"tanaka","age":19}')
=> {"name"=>"tanaka", "age"=>19}
```

`symbolize_names: true` をつけるとキーが `Symbol` になります。

```ruby
SON.parse('{"name":"tanaka","age":19}', symbolize_names: true)
=> {:name=>"tanaka", :age=>19}
```

### `ActionController::Parameters` は `Symbol` と `String` 両方で参照可能だが

Rails の parameter は `Symbol` と `String` 両方で参照できます。

```ruby
params[:email]
=> "sample@example.com"
params['email']
=> "sample@example.com"
```

ただし、他の Hash に `merge` しようとすると `String` しか残らないので、`Symbol` と `String` で値が違うなんてことに。。。

```ruby
new_params = { email: 'test@test.com' }.merge(params)
new_params[:email]
=> "test@test.com"
new_params['email']
=> "sample@example.com"
```

`with_indifferent_access` を付けることで、同じ動きを維持できます。

```ruby
new_params = { email: 'test@test.com' }.with_indifferent_access.merge(params)
new_params[:email]
=> "test@test.com"
new_params['email']
=> "test@test.com"
```

## `Exception` なのか `nil` なのか 

Ruby ではエラーになった場合、`Exception` を出すパターンと `nil` を返すパターンがあり、メソッドによって異なります。
特に、似たようなメソッドなのに違う動きをする場合もあるので、注意が必要です。

### `Time.parse`, `Time.zone.parse` の引数エラー

```ruby
Time.parse('hoge')
ArgumentError: no time information in "hoge"
```

```ruby
Time.zone.parse('hoge')
=> nil
```

`Time` と `Time.zone` 同じメソッドが用意されているので、使い勝手も同じかと思いきや、違うことがあるので、注意が必要ですね。

### `Integer` と `to_i` の引数エラー

```ruby
Integer('hoge')
ArgumentError: invalid value for Integer(): "hoge"
```

```ruby
'hoge'.to_i
=> 0
```

正直、`to_i` で `0` が返ってくるのは、使いにくくないかい ?


## "!" が付いてないのに破壊的なやつがいる

Ruby では破壊的メソッドの後には "!" が付いてるよ、と習いませんでしたか ?
`map!` とか `sort!` とか
自分でメソッド作る時も、"!" つけることで、使うときは注意してね、って分かりやすい。

ですが、全てに "!" がついているわけではないんですよ。。。


### `keep_if`, `delete_if` は破壊的

`Array` と `Hash` にある `keep_if`, `delete_if` メソッドは呼び出したオブジェクト自身が変更されます。


```ruby
num_list = [1, 2, 3, 4, 5]                    #=> [1, 2, 3, 4, 5]
odd = num_list.keep_if {|num| num.odd?}       #=> [1, 3, 5]
even = num_list.delete_if {|num| num.odd?}    #=> []
num_list                                      #=> []
```
まー、名前から見ても、分かりそうですし、
`delete_if` = `reject!`、`keep_if` = `filter!` なんですけど。

## 結論

何となくで実装せず、ちゃんと仕様を確認しよう。


## 参考にしたもの

- [Rubyの文字列とシンボルの違いをキッチリ説明できる人になりたい](https://qiita.com/Kta-M/items/53a13ef60e14fcb41193)
- [Time.parse と Time.zone.parse の違い](https://qiita.com/slightair/items/fa5f63016c0c848111a9)
- [String#to_iは数値に変換できない文字列に対しても例外を返さない](https://zenn.dev/yukito0616/articles/96f60046f94ac3)
- [【Ruby】「!」が付かない破壊的メソッドまとめ](https://qiita.com/k-penguin-sato/items/ab2267ca99d5aedcc40a)
- [How to merge Hash with Rails controller's params?](https://stackoverflow.com/questions/21090339/how-to-merge-hash-with-rails-controllers-params)
aws lightsail (ドメインの設定、メールの受信設定、FTP接続)

参考

https://liginc.co.jp/549866

# ドメインの設定 (web)

Amazon Lightsail にログイン
→ Networking
→ Create DNS zone

Enter the domain you have registered
にドメイン名を入力

ネームサーバーが表示されるのでメモ

ns-2549.awsdns-01.co.uk
ns-1134.awsdns-21.org
ns-634.awsdns-41.com
ns-5c6.awsdns-08.net


Assignments をクリックして、
ドメインを設定

![nagare2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/f2908c79-8c5c-db83-a85b-93ca026cfa56.png)


つづいて、DNSrecordsをクリック
Aレコードはすでに設定されているので、

AAAAレコードも設定しておこう。Resolves to下のコードをクリックするとサーバーを選択できる。
（IPV6版みたいな感じ。）

MXレコードは
メールサーバーに向けておく。


![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/7101f5c5-6d7f-cfc2-9540-053a114ee833.png)


# ムームードメインにログイン

弊社サービス以外 のネームサーバを選択し、
上記ネームサーバーを入力していく。

`これでドメイン設定OK`

# [受信のみ] メールアドレスの設定

とりあえず info@your.com に届いたメールを hoge@gmail.com に転送するだけ。
conohaのメールサーバーを利用します。


# conoha メールサーバーにログイン

メールサーバーを選択
→ドメイン追加

メール転送設定
ネームタグ 任意
送信元アドレス info@your.com
転送先アドレス hoge@gmail.com
転送方法 転送したあとにメールを削除する
迷惑メールフィルター OFF
ローカル配送 ON

メールアドレス作成

メールアドレスリスト
info@your.com も作る

SMTPサーバー mail77.conoha.ne.jp

をメモる。

# lightsail 側

Amazon Lightsail にログイン
→ Networking
→ Create DNS zone

Add recordをクリック

MX record
subdomain @ (空欄にすると入らないので。あっとにする)
priority 10
maps to mail77.conoha.ne.jp

これでメールが届くようになる。

確認等は
https://mxtoolbox.com/

ですると良い。

# [送信のみ] sendgridを利用して送信する

https://qiita.com/ma7ma7pipipi/items/c9598c0de46dd96f1172

# FTP接続

なんと vsftpd 無しでftp接続できちゃう。
今回はphpstormで。

amazon Lightsailにログインして「インスタンス」を選択

・接続の中のIPアドレスをコピー
・SSH接続で設定した 秘密鍵ファイルを用意

phpstorm で sftp を選択

![pem.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/ca66bbf7-ce9c-5e6f-c2eb-2990ccad39cf.png)

こんな感じで設定すればFTP接続ができちゃう。
AWSのリージョンで作成できるVPC数の上限値を引き上げる

# 経緯
AWSの各サービスには [サービスクォータ](https://docs.aws.amazon.com/ja_jp/general/latest/gr/aws_service_limits.html) と呼ばれる上限値があります。普段はあまり意識することがないのですが、
今回1つのアカウントにIAMユーザを12人作成し、大勢で使っているのでVPCのクォータに引っかかってしまいました。こんな感じのエラーになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2261111/bf6687dd-8a6f-b82b-1112-5b226261dcc0.png)

調べてみるとどうやらデフォルトでリージョンごとに作成できるVPCの数は最大 5 までしかありません。しかし増やすことはできるようです。もう少し引き上げたいのでやってみました。

# VPCクォータの引き上げをリクエストする

* Service Quotasのサービスを開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2261111/0ecf2da4-0e39-fae8-3b0a-418f84808c78.png)

* 左のメニューから「AWSのサービス」を開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2261111/23cc1997-0192-f642-b0ce-490d76b0d4d7.png)

* 項目がいっぱいあるので検索値で絞ります。今回はVPCなので Virtual と入れてみました。Virtual Private Cloudが残るので選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2261111/fc258b75-0a88-dadb-60fd-b66c5a770bb1.png)

* VPCに関するクォータ一覧が出て来ました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2261111/526785b0-2a78-d310-1c72-624ef2e3c75d.png)

* VPCs per Region リージョンごとのVPC、が今回変更したいクォータです。今はデフォルト値の５です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2261111/49b0fbf6-d6c7-5d59-b83e-6cd62b32fed3.png)

* 「クォータの引き上げをリクエスト」を押します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2261111/90d36546-ff55-4bc2-29be-b44dd4de9f66.png)

* 25でリクエストしてみます。なお、最大で100まで増やせるらしいです。増やしても追加費用はかかりません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2261111/694bad0f-ebb9-3bfe-02e3-3e7a8ee1b649.png)

* リクエストすると、リクエスト履歴が「保留中」に変わりました。いったんここまででサインアウトします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2261111/ac09a7df-fd0e-928e-48b1-45745d5ca2a5.png)

# リクエストの結果を確認する

* 翌日確認するとクォータが増えていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2261111/cef8d6a8-5c3d-a813-e55e-4496a4208f92.png)

無事目的達成です。
UdacityのNanodegreeレビュー　～Intro to Programming Nanodegree～

# はじめに
いま経済学系の学部に通っています。授業でプログラミングを少し勉強する機会があった。その授業がきっかけで、もっとプログラミングを学んでみたいと思うようになった。そこで自分で勉強できる教材をいろいろと探していた。
いざ探してみると、本やweb、スクールなどたくさんの手段があったので、とっても迷った。色々と迷った結果、Udacityの「Intro to Programming Nanodegree」が一番自分に合ってると思い受講してみた。
Udacityは海外のサービスで使ったことがない人もいると思う。そこで、実際に体験してみてどう思ったかについて書きたいと思う。

# 結論
__おすすめです！__

理由は３つある。
* **理由１：英語力が身につくから**
* **理由２：学習者目線でカリキュラムが組まれているから**
* **理由３：続けられる仕組みがあるから**

## おすすめな理由の前にデメリットも
Udacityの「Intro to Programming」、個人的にとてもおすすめだ。しかし、Udacityの受講を考えている人には少しネックになる部分についても知っておいてほしい。ネックな部分として、、
* **すべて英語である。** 動画と文章などで１つのレッスンが構成され、そのすべて英語である。
* **時間がかかる。** たしか、1.5時間くらいの学習を毎日続けたとして、3か月から4か月程度かかる量だ。

私が体験してみたところではこんな感じだ。

これから先は、おすすめな理由について書いていく！

## 理由１：英語力が身につくから
とにかく英語力が身につく。**なぜなら、約3か月間、毎日1時間から2時間くらい英語に触れていたら自然とそうなった**。ちなみにどれくらいの英語力が身についたかというと、、、
* **TOEIC Listen&Reading 815点**
    * リスニング　445点/495点
    * リーディング　370点/495点
* **会話できる。**
    * 外国人講師の話が分かるようになった。
    * 急に質問されても英語で回答できるようになった。

このプログラム「Intro to Programming Nanodegree」を受講すると、これくらいの英語力が身についてた。
## 理由２：学習者目線でカリキュラムが組まれているから
私がUdacityのカリキュラムが学習者目線で組まれていると思った理由は、2つあります。
**1. 1つ1つの授業が短く、わかりやすい**
**2. 動画、文章、そして演習を通して力が身につく**

それでは私がそう思ったわけを詳しく説明していく?
todo more
## 理由３：続けられる仕組みがあるから
全部のプログラムに続けられる仕組みが満載です。例えば、以下のようなものがあります。
* **プロや仲間に相談できる。**
* **自分の頑張りが可視化される。**

スタックや知恵袋みたいに、質問できる場所がある。あと、学習している人たちが応援し合う茶とルームも完備されている。だから、**詰まった時でもすぐに前に進めるし、頑張っている人に触発されて自分もやろう！って思える。**
あと、自分の進捗状況が見えるようになっている。また、自分の頑張りに応じてカレンダーの色が変わったりする。これが楽しくて、頑張っていた。**受験勉強の[スタディープラス](https://play.google.com/store/apps/details?id=jp.studyplus.android.app)みたいなイメージ。**

# まとめ
Udacityをやってみようかなって思う人の参考になれば幸いです。わからないことなどがありましたら、気軽に質問を井田抱ければと思う。
# 参考文献
* [Udacity Official site](https://www.udacity.com/)
Pythonの初期化処理

# __init__メソッド
　これはクラスからインスタンスを生成するために使用されるメソッドで、クラスの初期化の処理を担っています。
　Rubyで例えるとinitializeメソッドと同じで次のように記述するはずです。
```ruby
class クラス名
  def initialize(a,b,c)
       @a = a
       @b = b
       @c = c
  end
end
```

一方Pythonでは以下のように記述します。
```python
class クラス名:
  def __init__(self,a,b,c):
    self.a = a
    self.b = b
    self.c = c
```
と記述します。
これによりクラスのインスタンスを生成され、a,b,cの値は初期で使用される値となります。
pythonでは__init__メソッドの引数の中にselfが入っていますが、これによりクラスのインスタンスを生成しているので、
```python
def __init__(self, ~)
```
と覚えておくとよいかもしれません。
【rails入門】javascriptを用いてチェックボックスの値を維持する Ver-2.0

# はじめに
この記事は以前投稿した[【rails入門】javascriptを用いてリロードしてもチェックボックスの値を維持する（本題）](https://qiita.com/Naoya_pro/items/c3e8c450302aca6053f4)という記事でやっていたことと同じことをよりスマートに書いたものです！
プログラミング初心者の僕にコメントでご教授いただいたことに感謝してこの記事を書いています！それでは早速やっていきましょう！！
# 現状とやりたいこと
* ゲーム名がランダムで1つ表示されるようなガチャを作りたい
* タグ検索機能を使ってジャンルを絞り込めるようにしたい
* 絞り込む時に使用するチェックボックスを**リロードした時も、リロード前と同じ値を維持したい**

今回は3つ目の`リロードした時も、リロード前と同じ値を維持したい`これをやっていきます:scissors:

![Something went wrong]()

## 1.今のチェックボックス
現状こんな感じでチェックボックスをrailsで作っています
```ruby:gatya.html.erb
<%= form_tag({controller:"tweets",action:"gatya"}, method: :get) do %>
    <div class="game">
        <% if !@tweet.nil? %>
            <h1><%= @tweet.name %></h1>
        <% else %>
            <h1>no hit</h1>
        <% end %>
        <button type="submit" id="submit">
            <i class="fa-solid fa-arrows-rotate"></i>
            次へ
        </button>
    </div>
    ジャンル：
    <% Genre.all.each do |g| %>
        <%= check_box :genre_ids, g.name, checked:true, class:"check" %>
        <%= g.name %>
    <% end %><br>
    機種：
    <% Console.all.each do |t| %>
        <%= check_box :console_ids, t.name, checked:true, class:"check" %>
        <%= t.name %>
    <% end %><br>
<% end %>
```
大事なことは`check_box`に`class:"check"`が入っていることだけです！
## 2.javascriptを書いていく
今回は`sessionStorate`というものを使ってチェックボックスの値を保存します
* `sessionStorage`はブラウザを開いている間のみデータを保存できる
* `loacalStorage`はブラウザを閉じてもデータを維持できる

>参照：https://qiita.com/uralogical/items/ade858ccfa164d164a3b
```javascript:gatya.html.erb
<%= form_tag({controller:"tweets",action:"gatya"}, method: :get) do %>

    # 省略

<% end %>

<script>
    var object = {
        strageName: 'checkBoxStatus',
    };
    object.strageData = sessionStorage.getItem(object.strageName);
    object.strageData = object.strageData ? JSON.parse(object.strageData) : [];

    window.addEventListener('DOMContentLoaded', () => { //まずこのページ開いた時に動く
        object.checkBoxList = document.querySelectorAll('.check');
　　　　　　　　　　　　　　　　//class名がcheckの要素を全てlistに変えてobject.checkBoxListに格納する
        object.strageData.forEach((bool, i) => object.checkBoxList[i].checked = bool);
　　　　　　　　　　　　　　　　//1行上で取得した要素からチェックボックスのステータスをobject.strageDataに基づいて変更していく
    });

    window.addEventListener('beforeunload', () => { //リロードする直前に動く
        object.checkBoxList.forEach((elem, i) => object.strageData[i] = elem.checked);
        //リロードする直前にobject.strageDataの内容を更新している
        sessionStorage.setItem(object.strageName, JSON.stringify(object.strageData));
　　　　　　　　　　　　　　　　//更新した内容をsessionStorageに保存
    });
</script>
```
sessionStrageは辞書型のみ保存できるのでkeyとvalueが必要！なのでcheck_boxの値はlistとして保存できないので
* keyが　strageData
* valueが　[true, false, false, true, ...]
みたいな感じで保存してる↓↓↓
```
{
    strageData: [true, false, false, true, ...],
}
```


何か思ったことあれば、質問でも改良案でもコメントにてお待ちしております！！
それではバイバイバーーーい
Python学習のロードマップ(初心者が競馬予測AIを作るまで)

<h1>Python学習のロードマップ
  
`この記事はギャンブル狂であらゆるギャンブルの養分となってはいるもの頭脳明晰な友人養分くんとプログラミング歴半年の僕が競馬予測AIを作っていく不定期連載です。`
ここで僕は初心者の友人にどのようにPythonで機械学習で競馬予測ができるまで教えたのかを記しました。この記事はこんな方におすすめです。
「pythonの学習をしてみたいけど、どこからすればいいのかわからない」
「データ分析する職業への転職に興味がある、、」
「大学の授業でPythonを軽くかじったぐらいで機械学習なんか恐れ多い、」
僕の友達の養分君も完全未経験からデータ分析を軽々こなすぐらいまでなりました。ここではそのロードマップを記していこうと思います。
<h1>Step0!インプットよりもアウトプット

勉強始めとして入門書を買ってガツガツ勉強しようという方は少なくないと思います。これは数学などの勉強などの既存知識があるなら全然問題ないと思います。（他の言プログラミング語をしっかり学習した人ならOK!!)しかし算数でも最初は積み木を組み立てることから始めたり、英語でもわからなりに自己紹介したり挨拶をすることから始め何となくの感覚をつかむところから始めます。プログラミング勉強では最初の初心者の段階では参考書をまずガツガツやっても感覚としてわかっていないと理論的にもなかなか理解できないことがあるため初心者でもできるサイトでまずは感覚をつかんでいきましょう！

<h1>Step1！Progateの体験版で慣れる

最初におすすめするのが[Progate](https://prog-8.com/)です。初心者向けのサイトでイラストがとてもわかりやすく挫折なしで学習できます。最近プログラミングを独学で勉強した人ならこれやってない人いないよねってぐらい有名なサイトです。有料版もあるのですが無料版でも贅沢すぎるレッスンが受けれます！まずは無料でできるPython１とコマンド編を実践してみましょう。(コマンドは後からPythonを自分のパソコンにダウンロードするときに使います。）`養分君はこのレッスンを一時間ちょいで終わらせました、、賢い、、`

以下がprogateのリンクになります
[Progate](https://prog-8.com/)

<h3>Step(1-2)本屋さんに行って体系的にまとまった参考書を辞書として買おう

プログラミング勉強では最初の初心者の段階では参考書をまずガツガツやっても感覚としてわかっていないと理論的にもなかなか理解できない、、みたいな状況に息詰まって勉強を諦めてしまうみたいな状況に陥ることがあるのでまずはProgateで演習して慣れるというのが僕の意見でした。ここからの勉強でもアウトプット中心に行きますが何かわからないことがあった時に何か体系的にまとまった本を自分の教科書として持っていると辞書としても使えます。復習として持っていても非常に便利です。自分で本屋さんに行って実際に見てみて自分にあった参考書を買いましょう！！ここでは僕のおすすめの本も載せておきます。試し読み機能で自分に合うかどうかを確認してみてください。

みんなのPython
`これは筆者のおすすめで相棒の養分君もこれで勉強しました。難しすぎず易しすぎずといった感じです。`
入門Python3
`この本は多岐にわたる知識が網羅されていて入門的な知識から複素計算まで載っています。`
Python 1年生体験してわかる!会話でまなべる!プログラミングのしくみ
`絵本でPythonをわかりやすく解説してくれて躓くことなく必須の知識を教えてくれます`
<h1>Step3!Anacondaを自分のパソコンにインストールしてみよう

anacondaはPythonが自分のパソコンで実行できるアプリです。ここからの勉強で必要になってくるのでダウンロードしましょう。WindowsとMacなど自分のOSによってダウンロードの仕方が違うので以下のサイトを参考にしてみてください


[Windowsの人](https://www.python.jp/install/anaconda/windows/install.html)

[Macの人](https://www.python.jp/install/anaconda/macos/install.html)


`この記事は後半に続きます`
cscの作法 その123

# 概要
cscの作法、調べてみた。
managed directxやってみた。
キー入力してみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/e2c404b4-70f5-df1d-a4c5-36da51e67805.png)

# サンプルコード

```
using System;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

namespace mdx
{
	public partial class Form1 : Form {
		private Device device = null;
		private Mesh mesh = null;
		float x = 0,
			y = 0,
			z = 0;
		private Matrix rot = Matrix.Identity;
		public Form1() {
			Text = "Form1";
			this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
			PresentParameters pp = new PresentParameters();
			pp.Windowed = true;
			pp.SwapEffect = SwapEffect.Discard;
			device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, pp);
			mesh = Mesh.Cylinder(device, 0.2f, 0.8f, 1.5f, 8, 1);
			this.Paint += Form1_Paint;
			this.KeyDown += new KeyEventHandler(Form1_KeyDown);
		}
		private void Form1_Paint(object sender, PaintEventArgs e) {
			rot.Multiply(Matrix.RotationYawPitchRoll(y, x, z));
			device.Transform.View = Matrix.LookAtLH(new Vector3(0.0f, 1.0f, 7.0f), new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f));
			device.Transform.Projection = Matrix.PerspectiveFovLH((float)(Math.PI / 4), 1.0f, 0.1f, 1000.0f);
			device.RenderState.Lighting = false;
			device.Clear(ClearFlags.Target, Color.DarkBlue, 1.0f, 0);
			device.BeginScene();
			device.SetTransform(TransformType.World, Matrix.Identity);
			device.Transform.World = rot;
			mesh.DrawSubset(0);
			device.EndScene();
			device.Present();
			this.Invalidate();
		}
		private void Form1_KeyDown(object sender, KeyEventArgs e) {
			switch (e.KeyCode)
			{
			case Keys.Escape:
				this.Close();
			break;
			case Keys.F1:
			break;
			case Keys.F2:
				Console.WriteLine("f2");
			break;
			case Keys.Up:
				z -= (float) Math.PI / 90f;
			break;
			case Keys.Down:
				z += (float) Math.PI / 90f;
			break;
			case Keys.Z:
				x -= (float) Math.PI / 90f;
			break;
			case Keys.A:
				x += (float) Math.PI / 90f;
			break;
			case Keys.Right:
				y -= (float) Math.PI / 90f;
			break;
			case Keys.Left:
				y += (float) Math.PI / 90f;
			break;
			case Keys.Shift:
			break;
			}
		}
		[STAThread]
		public static void Main() {
			Application.Run(new Form1());
		}
	}
}





```

以上。
cscの作法 その122

# 概要
cscの作法、調べてみた。
managed directxやってみた。
テキストを表示してみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/522075ca-48b6-c7fe-40cd-3f30e2ed1c60.png)

# サンプルコード

```

using System;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

namespace mdx
{
	public partial class Form1 : Form {
		private Device device = null;
		private Microsoft.DirectX.Direct3D.Font font;
		private String info;
		public Form1() {
			Text = "Form1";
			this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
			PresentParameters pp = new PresentParameters();
			pp.Windowed = true;
			pp.SwapEffect = SwapEffect.Discard;
			device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, pp);
			info = string.Format("あす");
			System.Drawing.Font winFont = new System.Drawing.Font("MS ゴシック", 50, FontStyle.Regular);
			font = new Microsoft.DirectX.Direct3D.Font(device, winFont);
			font.PreloadText(info);
			this.Paint += Form1_Paint;
		}
		private void Form1_Paint(object sender, PaintEventArgs e) {
			device.Clear(ClearFlags.Target, Color.DarkBlue, 1.0f, 0);
			device.BeginScene();
			device.SetTransform(TransformType.World, Matrix.Identity);
			font.DrawText(null, info, 50, 50, Color.Red);
			device.EndScene();
			device.Present();
			this.Invalidate();
		}
		[STAThread]
		public static void Main() {
			Application.Run(new Form1());
		}
	}
}






```

以上。
cscの作法 その121

# 概要
cscの作法、調べてみた。
managed directxやってみた。
RotationYawPitchRollで回転してみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/09252592-6bd4-8cf8-6330-21d948764abf.png)


# サンプルコード

```

using System;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

namespace mdx
{
	public partial class Form1 : Form {
		private Device device = null;
		private Mesh mesh = null;
		float x = 0,
			y = (float) Math.PI / 2 / 20,
			z = 0;
		private Matrix rot = Matrix.Identity;
		public Form1() {
			Text = "Form1";
			this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
			PresentParameters pp = new PresentParameters();
			pp.Windowed = true;
			pp.SwapEffect = SwapEffect.Discard;
			device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, pp);
			mesh = Mesh.Cylinder(device, 0.2f, 0.8f, 1.5f, 8, 1);
			rot.Multiply(Matrix.RotationYawPitchRoll(y, x, z));
			this.Paint += Form1_Paint;
		}
		private void Form1_Paint(object sender, PaintEventArgs e) {
			rot.Multiply(Matrix.RotationYawPitchRoll(y, x, z));
			device.Transform.View = Matrix.LookAtLH(new Vector3(0.0f, 1.0f, 7.0f), new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f));
			device.Transform.Projection = Matrix.PerspectiveFovLH((float) (Math.PI / 4), 1.0f, 0.1f, 1000.0f);
			device.Clear(ClearFlags.Target, Color.DarkBlue, 1.0f, 0);
			device.BeginScene();
			device.SetTransform(TransformType.World, Matrix.Identity);
			device.RenderState.Lighting = false;
			device.Transform.World = rot;
			mesh.DrawSubset(0);
			device.EndScene();
			device.Present();
			this.Invalidate();
		}
		[STAThread]
		public static void Main() {
			Application.Run(new Form1());
		}
	}
}





```

以上。
cscの作法 その120

# 概要
cscの作法、調べてみた。
managed directxやってみた。
クオータニオンで回転してみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/b4635105-dc41-cf40-90a3-a1a6cb85afef.png)

# サンプルコード

```
using System;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

namespace mdx
{
	public partial class Form1 : Form {
		private Device device = null;
		private Mesh mesh = null;
		float x = 0,
			y = (float) Math.PI / 2 / 20,
			z = 0;
		private Quaternion qua = Quaternion.Identity;
		public Form1() {
			Text = "Form1";
			this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
			PresentParameters pp = new PresentParameters();
			pp.Windowed = true;
			pp.SwapEffect = SwapEffect.Discard;
			device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, pp);
			mesh = Mesh.Cylinder(device, 0.2f, 0.8f, 1.5f, 8, 1);
			qua.Multiply(Quaternion.RotationYawPitchRoll(x, y, z));
			this.Paint += Form1_Paint;
		}
		private void Form1_Paint(object sender, PaintEventArgs e) {
			qua.Multiply(Quaternion.RotationYawPitchRoll(x, y, z));
			device.Transform.View = Matrix.LookAtLH(new Vector3(0.0f, 1.0f, 7.0f), new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f));
			device.Transform.Projection = Matrix.PerspectiveFovLH((float) (Math.PI / 4), 1.0f, 0.1f, 1000.0f);
			device.Clear(ClearFlags.Target, Color.DarkBlue, 1.0f, 0);
			device.BeginScene();
			device.SetTransform(TransformType.World, Matrix.Identity);
			device.RenderState.Lighting = false;
			device.Transform.World = Matrix.RotationQuaternion(qua);
			mesh.DrawSubset(0);
			device.EndScene();
			device.Present();
			this.Invalidate();
		}
		[STAThread]
		public static void Main() {
			Application.Run(new Form1());
		}
	}
}





```

以上。