OmniAICreator/Qiita-1.07M huggingface dataset:
Firebase Authの注意点２つと対策コード (弱いパスワードを正規表現で対策 / 不正ログイン防止)

# 問題です 🤔
FirebaseAuthは弱いパスワード登録を拒否して`auth/weak-password`というエラーを返す機能があります。
[Auth \| JavaScript SDK  |  Firebase](https://firebase.google.com/docs/reference/js/firebase.auth.Auth#error-codes_3)

では、**以下の激弱パスワード**は拒否してくれるでしょうか？
`password： 1234567890`

**答えは、「登録できてしまう」です。** (2019/10月時点)
以下に対策コードを紹介しますので、ぜひ活用して下さい。

# はじめに
今回はFirebase Authenticationの注意点として、不正ログイン対策等を説明します :smile:
以下２点に注意することで、より良いセキュリティ対策を目指しましょう。

# 注意点1： 弱いパスワードは拒否しよう 
この激弱パスワード、Firebase Authは拒否してくれません :cry: (2019/10月時点)
`password： 1234567890`

Firebase Authを使っていても弱いパスワードで登録できてしまうことに注意しましょう。
ただしFirebase Authにはレートリミットが実装されているため深刻な欠点という訳では無いと思います。

とはいえ、何らかの対策をしておくことが望ましいでしょう。
具体的には`英数小文字大文字混在でXX文字以上などの制限`を設けておくと良いと思います。

上記のレートリミットがあることも考慮して、私は以下のような正規表現で対策しています。

### 対策コード(正規表現)
```regex.js
// 10文字以上であること
// 英数字が混在していること
// 大文字と小文字のアルファベットが含まれること
regex: /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[0-9a-zA-Z]{10,}$/
```

参考： [jquery - javascript regex for password containing at least 8 characters, 1 number, 1 upper and 1 lowercase - Stack Overflow](https://stackoverflow.com/questions/14850553/javascript-regex-for-password-containing-at-least-8-characters-1-number-1-uppe)

# 注意点2： 登録メールアドレスは確認しよう
Firebase Authのメール/パスワード登録には仮登録という段階がありません。
例えば他人のメールアドレス/自由なパスワードで登録できてしまいます。

その場合、メールアドレスを使われた人が自分のアドレスで登録しようとすると
`auth/email-already-in-use`といったエラーが出て登録できなくなってしまいます。
 [Auth \| JavaScript SDK  |  Firebase](https://firebase.google.com/docs/reference/js/firebase.auth.Auth#error-codes_3)

対策としてメールを送り開封確認しましょう。(無料で送信可能)
[Firebase のユーザーを管理する  \|  Firebase](https://firebase.google.com/docs/auth/web/manage-users?hl=ja#send_a_user_a_verification_email)

```sample.js
var user = firebase.auth().currentUser;

user.sendEmailVerification().then(function() {
  // Email sent.
}).catch(function(error) {
  // An error happened.
});
```

上記の `sendEmailVerification()` で送信されたメール内のリンクをクリックすると
Firebaseが開封を検知して以下のように記録されます。

- JWT内に記載されているメール確認フラグ `emailVerified` がtrueになる
- Firebase Admin SDK で確認できるアカウントのフラグ `emailVerified` がtrueになる

このフラグを利用して

- メール未確認のJWTは拒否(POST等に対してエラーを返す)
- メール未確認のアカウントを定期的に削除

といった対策を行いましょう。
これらを実装することで、よくある「仮登録」の段階を実現できると思います。

以上、拙い記事でしたが何かのご参考になれば幸いです🙇‍♂️
Rustでcharを&strに変換したい

初投稿です。
初心者あるあるの文字列操作の一例を投稿します。
# 0. 環境
- rustc 1.38.0 (625451e37 2019-09-23)
- binary: rustc
- commit-hash: 625451e376bb2e5283fc4741caa0a3e8a2ca4d54
- commit-date: 2019-09-23
- host: x86_64-pc-windows-msvc
- release: 1.38.0
- LLVM version: 9.0

# 1. 考え方
char -> String -> &str の順で変換します。

# 2. 例
```rust
fn main() {
    let c = 'a';
    let c_string: String = c.to_string();

    let c_ampersand_str: &str = &c_string;
    // let c_ampersand_str: &str = &c.to_string(); でもOKです

    println!("{}", c_ampersand_str);
}
```

# 3. 終わりに
冒頭にもありますが初投稿です。
最近はRustにはまっているので時間があれば, Rust関連の記事を投稿すると思います。
【Git】HEADとは？git resetを例にして動きの確認【しょうたいふめい】

「Gitでワークツリーとインデックスは分かった。」
「でも、そういえば**HEAD**って何者？」
「なんか`git log`とかで出てはくるよね…」

ここを理解していなかったのでまとめます。
そもそもHEADを見て見ぬ振りをしていました。

この概念の理解で各コマンドの理解が一段回進んだ実感があります！

誤り等あればご指摘頂けますと幸いです。

## この記事が役立つ人
- `git reset`とかでググった情報をそのまま使ってしまう
- 結果、思ってたのと違う挙動を発して現在位置を見失いテンパる
- Gitの構造が良く分かっていない
- Git初心者

## HEADってどういうもの？
### 解釈
**今ココのコミットにいるよ**という情報

### 公式サイトの説明
「あなたが作業しているローカルブランチへのポインタ」

### その他関連用語
#### インデックス
`commit`待ちの情報。
`add`すると変更される。

#### ワークツリー
自分のPC内の情報。
エディタで編集し、ファイルを保存したら変更される。

## 実際、状態はどう動くの？
`git reset`の各オプションでの理解が分かりやすいです。

過去の状態：　Before
現在の最新状態：　After
として、考えてみます。

今は全部Afterなので、こういう状態ですね。
- HEAD：　After
- インデックス：　After
- ワークツリー：　After

解釈は、以下のようなイメージです。

のび太がしずちゃんに告白して失敗したシーンを例にします。

せっかく作戦を練ってプレゼントを渡したら成功するんじゃないかと考えたのに、失敗して過去に戻りたいというシチュエーションです。

- HEAD　プレゼントを渡して告白して失敗した後
- インデックス　プレゼントが完成している
- ワークツリー　プレゼントを渡す作戦を練り終わった


```zsh
$ git reset --soft HEAD
```
- HEAD：　**Before**
- インデックス：　After
- ワークツリー：　After

【利用シーン】
直前のコミットのみを取り消す際に使う。
addした情報は残る。

【解釈】
しずちゃんに告白する直前に戻る。
「プレゼントの渡し方が悪かったんだ！渡し方を変えるために過去に戻ろう！」

- HEAD　プレゼントを渡す前
- インデックス　プレゼントが完成している
- ワークツリー　プレゼントを渡す作戦を練り終わった

```zsh
$ git reset HEAD
```
※—mixedオプションをつけたのと同じ。
- HEAD：　**Before**
- インデックス：　**Before**
- ワークツリー：　After

【利用シーン】
addしたのを取り消したい。
addしたファイルにも不備があることが分かった場合。

【解釈】
しずちゃんに告白する前の状態に戻り、かつ用意したプレゼントも変える。
「そもそもプレゼントが悪かったんだ！作り直そう！」

- HEAD　プレゼントを渡す前
- インデックス　プレゼントは作っていない
- ワークツリー　プレゼントを渡す作戦を練り終わった

```zsh
$ git reset —hard HEAD
```
- HEAD：　**Before**
- インデックス：　**Before**
- ワークツリー：　**Beofre**

【利用シーン】
やらかした！全てなかったことにしたい！

【解釈】
そもそも作戦を練り直す。
「そもそも作戦自体が悪かったんだ！プレゼント渡すんじゃなくて他のこと考えよう！」

- HEAD　プレゼントを渡す前
- インデックス　プレゼントは作っていない
- ワークツリー　作戦は白紙

## まとめ
Gitは奥深いですね。

何回ものび太を頭の中でタイムスリップさせて構造の理解をしました。
今も頭の中で響きます。「ドラえもーーーーーーーん！」

## 参考にさせて頂いたサイト（いつもありがとうございます）
[GitのHEADとは何者なのか - Qiita](https://qiita.com/ymzk-jp/items/00ff664da60c37458aaa)
[いろいろモヤッとしていた git 初心者が腑に落ちるまで - Qiita](https://qiita.com/alt-core/items/d648b590fba3d389efd1)
[難しいGitコマンドは、仕組みから理解してみよう - Qiita](https://qiita.com/_ha1f/items/2dca1047c57d4f0bd465)
[【永久保存版】Gitのあらゆるトラブルが解決する神ノウハウ集を翻訳した - LABOT 機械学習ブログ](https://blog.labot.jp/entry/2019/07/01/183204)
[Git - ブランチとは](https://git-scm.com/book/ja/v2/Git-%E3%81%AE%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81%E6%A9%9F%E8%83%BD-%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81%E3%81%A8%E3%81%AF)
超簡単！！！10秒で自分のタスクスケジューラを作れる

<h1>簡単に作成できる手順は↓</h1>
<h2>１．中身</h2>
```vb:TaskTimer.vbs
dim input1,input2
input1=InputBox("[HH24:mm:ss]に提示メッセージを表示させるか？","時刻入力",FormatDateTime(time,vbLongTime))
input2=InputBox("提示メッセージ内容を書いてください。","メッセージ入力","一息を入れましょう！ or 会議１０分前！")
WScript.Sleep DateDiff("s",FormatDateTime(time,vbLongTime),input1)*1000
msgbox input2,vbSystemModal,"Warning"
```

```vb:簡易AlertTimer.vbs
ret1 = InputBox("[HH24:mm:ss]に次のAlert Messageを表示させます","※将来の時刻入力",FormatDateTime(time,vbLongTime))
ret2 = InputBox("Alert内容を記入てください。","メッセージ入力","一息を入れましょう！ or 会議１０分前！")
NewDate = DateDiff("s",FormatDateTime(time,vbLongTime),ret1)
WScript.Sleep NewDate*1000
MsgBox ret2,vbSystemModal,"★Alert"
```
<h2>２．外部ファイル作成</h2>
上記の中身を名前自由につける拡張子をvbsとする外部ファイルへ作成、保存。
<h2>３．試行</h2>
作成ファイルをダブルクリックして実行
<br>
<font color="red">※保存文字コードはSJISでOK、UTF-8はNG</font>
<font color="red">※Windows7,10にて実行試験済み</font>
<font color="red">※設定Alert時刻を将来時刻に設定するように（現時点以前にするとエラー発生してしまう）</font>
【初心者/新人SE向け】使用しているツールと主要コマンド

#使用しているツールと主要コマンド

##記憶喪失になった時の為用メモ

###■ツール
・A5SQL
・sqldeveloper（ストアドのコンパイルがほとんど）
・Teraterm
・WinSCP

###■サーバー上で使用する主要コマンド
#####・カレントディレクトリ変更
cd ディレクトリ

#####・ファイル一覧
ls -la

#####・ファイル移動
mv 移動元 移動先

#####・ファイルコピー
cp -p コピー元 コピー先

#####・ファイル内容表示
cat ファイル名
view ファイル名（主にログの確認）

#####・ファイル変更
vi ファイル名

#####・スケジューラ設定表示
crontab -l

#####・スケジューラ設定変更
crontab -e
  後はviエディタとなります。

#####・ファイルの追記確認(主にログ)
tail -f ファイル名
ECRでPush時に脆弱性スキャンするように設定する

# ECR上のDockerイメージを脆弱性診断する
[数日前からQiitaでも話題になってました](https://qiita.com/portfield_slash/items/8d27eb29eb8530eae546#comment-6c5d3f7442f5046cdbad)が、ついにECRの標準機能として脆弱性診断が追加されました。現状ではあくまでもベースのOS部分だけの診断になりますが、無料で利用できますし使わない理由はないと思います。

公式発表
[Native Container Image Scanning in Amazon ECR](https://aws.amazon.com/jp/blogs/containers/amazon-ecr-native-container-image-scanning/)

# Scan On Pushの有効化
既存のリポジトリについては、scan on pushを有効化しておくと便利です。
僕はTypeScriptで一括処理しました。ご参考までにコード載せておきます。

追記
未スキャンのリポジトリに対してスキャンも実行するように変更。

```typescript
import ECR = require("aws-sdk/clients/ecr");

const ecr = new ECR();

class Main {

    async run() {
        const repos = await ecr.describeRepositories().promise();
        if (!repos.repositories) {
            return
        }

        // Enable Scan on Push
        for (const repo of repos.repositories) {
            const {repositoryName} = repo
            if (!repo.imageScanningConfiguration.scanOnPush) {
                console.log(`Enable scanOnPush for ${repositoryName}`)
                await ecr.putImageScanningConfiguration({
                    repositoryName,
                    imageScanningConfiguration: {
                        scanOnPush: true
                    }
                }).promise()
            }
        }

        // Execute Manual Scan when there's no scan result
        for (const repo of repos.repositories) {
            const {repositoryName} = repo
            const result = await ecr.listImages({
                repositoryName: repo.repositoryName,
                maxResults: 1000
            }).promise()
            for (const imageId of result.imageIds) {
                const {imageTag} = imageId
                try {
                    await ecr.describeImageScanFindings({imageId, repositoryName}).promise()
                } catch (e) {
                    if (e.name === "ScanNotFoundException") {
                        console.log(`Start scan for ${repositoryName}:${imageId.imageTag}`)
                        await ecr.startImageScan({imageId, repositoryName}).promise()
                    }
                }
            }
        }
    }
}

new Main().run().finally();
```
「M5StickC [ obnizOS + HobbyLite ]」を購入して、電源が入らないと困っている人が最初に見る記事

# この記事は
[M5StickC [ obnizOS + HobbyLite ]](https://obniz.myshopify.com/collections/devices/products/m5stickc-obnizos-installed)を購入して、電源が入らないと困って取り合えずサポートにメール送った後にフォーラムやらTwitterやら見たら解決した。
数日後、サポートから回答が返ってきたメールに書かれていた使用方法を、折角なので~~供養~~連携しようという内容です。
# 使用手順
1. PCと接続し、シリアルポートよりobnizIDのご確認をお願い致します[^1]
　https://obniz.myshopify.com/pages/how-to-confirm-the-obnizid-of-m5stickc
 
2. シリアルポートより、wifi設定を行ってください[^2]
　https://obniz.io/ja/doc/obnizos/os_networksetup

3. node.jsやHTML等よりご利用ください。m5stickc.js を使用いただくと、手軽にディスプレイを使用することができます。
　https://github.com/obniz/m5stickcjs

[^1]: あまりに似たような質問が多かったのか、新しく設置されたページ
[^2]: ターミナルが文字化けする人は、速度=115200、データビット=8、ストップビット=1、パリティ=N、改行コード=CR+LF で試してみてネ
ULID生成順を保持する

# TL;DR;
https://github.com/ulid/spec#monotonicity
を参照
Kotlin or Javaの方法を求めてきた方はulid.nextValue().increment()を使用
# 前提
https://github.com/ulid/spec
Kotlin 1.3.50
[huxi ulid](https://github.com/huxi/sulky/tree/master/sulky-ulid)を使用
kotlin Scratchにて実験
## 失敗例
```kotlin
import de.huxhorn.sulky.ulid.ULID

val ulid = ULID()
val pairs = (0..1000).map {
  val now = System.currentTimeMillis()
  Pair(now, Pair(it, ulid.nextULID(now)))
}
val sorted = pairs.sortedBy { it.second.second }
println("\n\n\n" + sorted.take(10).joinToString("\n") { Pair(it.first, it.second.first).toString() })
//scratch.kts:9 (1571214567664, 0)
//scratch.kts:9 (1571214567665, 5)
//scratch.kts:9 (1571214567665, 1)
//scratch.kts:9 (1571214567665, 2)
//scratch.kts:9 (1571214567665, 4)
//scratch.kts:9 (1571214567665, 7)
//scratch.kts:9 (1571214567665, 6)
//scratch.kts:9 (1571214567665, 3)
//scratch.kts:9 (1571214567666, 15)
//scratch.kts:9 (1571214567666, 10)
```
同じミリ秒内に生成された物の順番は保証されない。
## 成功例
```kotlin
import de.huxhorn.sulky.ulid.ULID
 
val ulid = ULID()
var value = ulid.nextValue()
val pairs = (0..1000).map {
  val now = System.currentTimeMillis()
  Pair(now, Pair(it, value.increment().toString()))
}
val sorted = pairs.sortedBy { it.second.second }
println("\n\n\n" + sorted.take(10).joinToString("\n") { Pair(it.first, it.second.first).toString() })
//scratch.kts:10 (1571215418684, 0)
//scratch.kts:10 (1571215418685, 1)
//scratch.kts:10 (1571215418685, 2)
//scratch.kts:10 (1571215418685, 3)
//scratch.kts:10 (1571215418685, 4)
//scratch.kts:10 (1571215418685, 5)
//scratch.kts:10 (1571215418685, 6)
//scratch.kts:10 (1571215418685, 7)
//scratch.kts:10 (1571215418685, 8)
//scratch.kts:10 (1571215418685, 9)
```
```kotlin
var value = ulid.nextValue()
  Pair(now, Pair(it, value.increment().toString()))
```
前の値を保持しておいてincrementしているだけだがgithubには載っていなかったのでまとめた。
BabylonJS を試す

ES6: [ES6 - Babylon.js Documentation](https://doc.babylonjs.com/features/es6_support)
Tutorial: [Babylon.js Documentation](https://doc.babylonjs.com/babylon101/)
`yarn add @babylonjs/core` Typescript declaration も含まれる。

## Getting started
[First Steps - Babylon.js Documentation](https://doc.babylonjs.com/babylon101/first)を参考に触ってみる。Typescriptを使いたいのでとりあえずparcelでプロジェクトを立ててみる。

```bash
yarn add parcel @babylonjs/core typescript
```

```package.json
{
  "private": true,
  "scripts": {
    "start": "parcel serve watch src/*.html --open"
  },
  "dependencies": {
    "@babylonjs/core": "^4.0.3",
    "parcel": "^1.12.4",
    "typescript": "^3.6.4"
  }
}
```

```index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <style>
  html, body {
    overflow: hidden;
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
  }

  #renderCanvas {
    width: 100%;
    height: 100%;
    touch-action: none;
  }
  </style>
  <title>Babylon Playground</title>
  <script defer src="./app.ts"></script>
</head>
<body>
  <canvas id="renderCanvas" touch-action="none"></canvas>
</body>
</html>
```

```app.ts
import {
  Engine,
  Scene,
  ArcRotateCamera,
  Vector3,
  HemisphericLight,
  MeshBuilder,
} from '@babylonjs/core';

const canvas = document.getElementById("renderCanvas") as HTMLCanvasElement;
const engine = new Engine(canvas, true);
const scene = new Scene(engine);
const camera = new ArcRotateCamera("Camera", Math.PI / 2, Math.PI / 2, 2, new Vector3(0,0,5), scene);
new HemisphericLight("light1", new Vector3(1, 1, 0), scene);
MeshBuilder.CreateSphere("sphere", {diameter:2}, scene);

camera.attachControl(canvas, true);

engine.runRenderLoop(() => { 
  scene.render();
});

window.addEventListener("resize", () => { 
  engine.resize();
});
```

玉が表示される。最初、玉を動かしてると思ったがよく読んだらカメラを動かしている。

## FPSを表示する
`engine.getFps().toFixed()` で現在のFPSを取得する。`RenderLoop`で`$.innerHTML`とかするとそれじたいがFPSを大きく下げるのでダメ。canvas上にUIを設置するか。もしくは仮想DOMライブラリでUIを表現するのがよさそう。
Goでよく見るnewとNewを調べたときのメモ

# はじめに
Goのソースコードを読んでいて、構造体関連で `new` や `New` をよく見かけていたのですが、それぞれの意味や違いをあまり理解していなかったので、それらを調べたときのメモです。

# new
newは指定した型のポインタ型を生成する関数です。
例えば、構造体型のポインタ型を生成できます。

```go:newを使った初期化
type person struct {
	height float32
	weight float32
}

func main() {
	p := new(person)
	p.height = 182.0
	p.weight = 75.5
	fmt.Println(p) // &{182 75.5}
	fmt.Printf("%T", p) // *main.person person型のポインタであることがわかる
	fmt.Println()
	fmt.Printf("%p", p) // 0xc00001e060 もちろんアドレスもある
}
```

構造体型のポインタ型を生成する手段としては、他にアドレス演算子を使う方法もあります。どちらも動作上殆ど同じです。

```go:アドレス演算子を使った初期化
func main() {
	p := &person{height: 182.0, weight: 75.5}
	fmt.Println(p) // &{182 75.5}
}
```

構造体の初期化する際は、構造体のフィールドを参照共有するために `newを使う方法` か `アドレス演算子を使う方法` のいずれかでポインタ型にすることが多いかなと思います。

また、newは構造体以外の値型にも参照型の変数にも使用できます。
しかしながら、このような使用は普段のソフトウェア開発では滅多にありません。現実的には構造体とnewはセットで使うことが多いです。

```go
func main() {
	a := new(int)
	fmt.Println(a) // 0xc00001e060
}
```

# New
Goにはコンストラクタが用意されていません。
しかし、コンストラクタのようなものは実装できます。その時の関数名として通例、 `New + 構造体名` が適用されます。

```go
type person struct {
	height float32
	weight float32
}

func NewPerson(height, weight float32) *person{
	return &person{height: height, weight: weight}
}

func main() {
	p := NewPerson(182.0, 75.5)
	fmt.Println(p) // &{182 75.5}
}
```

# まとめ
- newは構造体の初期化でよく使う
- Newはコンストラクタの単なる命名における慣例
【PostgreSQL】VB.net フォームアプリケーションでSQLを操作するクラス(自分用)



フォームで呼び出す際は、引数にDataGridViewオブジェクトとSQL文を指定します。

このモジュールを作った後にMySQL用のモジュールも作りましたが
こっちの方が効率がいいのかな～とか思いながらアレンジしていこうと思います。


```vb
Imports Npgsql
Public Class PostgreSQL
    Const DATABASE As String = "Server=サーバーのアドレス;Port=ポート番号;User Id= ユーザー名;Password=パスワード;Database=データベース名;"
    
    Sub INSERT_SQL(strSQL As String)
        Try
            Using conn As NpgsqlConnection = New NpgsqlConnection(DATABASE)
                conn.Open()
                Dim command As NpgsqlCommand = New NpgsqlCommand(strSQL, conn)
                Dim sResult As String = command.ExecuteScalar()
            End Using
        Catch
            MsgBox("送信に失敗しました。", vbCritical + vbOKOnly)
        End Try
    End Sub

    Sub SELECT_ALL_SQL(dataGRID As DataGridView, dbTable As String)
        Try
            Using conn As New NpgsqlConnection(DATABASE)
                conn.Open()
                Dim cmd As NpgsqlCommand = New NpgsqlCommand("SELECT * FROM " & dbTable, conn)
                Dim da As NpgsqlDataAdapter = New NpgsqlDataAdapter(cmd)
                Dim dt As DataTable = New DataTable()
                da.Fill(dt)
                dataGRID.DataSource = dt
            End Using
        Catch
            MsgBox("データの取得に失敗しました。", vbCritical, vbOKOnly)
        End Try
    End Sub

    Sub SELECT_WHERE_SQL(dataGRID As DataGridView, strSQL As String)
        Try
            Using conn As New NpgsqlConnection(DATABASE)
                conn.Open()
                Dim cmd As NpgsqlCommand = New NpgsqlCommand(strSQL, conn)
                Dim da As NpgsqlDataAdapter = New NpgsqlDataAdapter(cmd)
                Dim dt As DataTable = New DataTable()

                da.Fill(dt)
                dataGRID.DataSource = dt
            End Using
        Catch
            MsgBox("データの取得に失敗しました。", vbCritical, vbOKOnly)
        End Try
    End Sub

    Sub DELETE_SQL(strSQL As String)
        Try
            Using conn As NpgsqlConnection = New NpgsqlConnection(DATABASE)
                conn.Open()
                Dim command As NpgsqlCommand = New NpgsqlCommand(strSQL, conn)
                Dim sResult As String = command.ExecuteScalar()
            End Using
            MsgBox("データを消去しました。", vbInformation + vbOKOnly)
        Catch
            MsgBox("データを消去しました。", vbCritical + vbOKOnly)
        End Try
    End Sub

    Sub UPDATE_SQL(strSQL As String)
        Try
            Using conn As NpgsqlConnection = New NpgsqlConnection(DATABASE)
                conn.Open()
                Dim command As NpgsqlCommand = New NpgsqlCommand(strSQL, conn)
                Dim sResult As String = command.ExecuteScalar()
            End Using

            MsgBox("データを更新しました。", vbInformation + vbOKOnly)
        Catch
            MsgBox("データを更新しました。", vbCritical + vbOKOnly)
        End Try
    End Sub

End Class
ガントチャートって何？〜とりあえずこれだけは知っておこう〜

　プロジェクト管理でよく目にするガントチャート。作成方法や運用のポイント、様々なツールの使用方法などを解説していきたいと思います。
今回は、その第１回、そもそもガントチャートとは何か？についてお話しします。

## （定義）ガントチャートとは
　ガントチャート（Gantt chart）は、作業計画とその進行状況を視覚的に把握するたための棒グラフの一種です。
　アメリカ人経営コンサルタント、ヘンリー・ガント（Henry Gantt）が工場での工程管理を行うために考案しました。

　チャートは、左右２つのブロックの組み合わせで構成され、左側のブロックは、プロジェクトの完了に必要な作業をリストアップした表、
右側ブロックはカレンダーの時系列上に各作業の実施時期を、作業ボリュームと実施順序を加味して配置した棒グラフです。
　この際、作業リストの作成には、一般的にＷＢＳ(Work Breakdown Structure)という手法を用います。

　ガントチャートを用いると、作業リストによる網羅性や増減の調整と、棒グラフによるスケジュールの視覚的な把握が同時に行えるため、
製造工程の管理だけでなく、様々な用途で用いられています。

例）ガントチャート
![gantt-chart-basic_gantt-sample1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518202/5601fc0d-19ca-be8e-a1a7-d428438a5f34.png)

## ガントチャートを利用するメリット
　ガントチャートは、作業管理表と、カレンダー、棒グラフの特徴を併せ持っているため、
ガントチャートを利用すると、下記のようなメリットがあります。


#### ■ ガントチャートを利用するメリット

* 作業の進捗状況を視覚的に表現するため、作業の開始・終了時期、順序、進捗状況などが把握しやすい
* スケジュールに抜け漏れ、人的リソースに無理がないかをチェックできる
* リスケジュールが必要になった場合、グラフ上でタスクの再配置ができる
* 管理者やエンジニア、顧客など、リテラシーの違う関係者間で状況を共有できる

　一方、作業数が多くなってくるとチャートが広大になり視覚的な検証効果が低下するなど欠点もりますので、別途、それらを補って運用する必要があります。


## ガントチャート作成手順
　ガントチャートは大まかに下記のような手順で作成します。

#### ■作成手順
1. WBSを使用してプロジェクトを具体的な作業単位まで分割する
2. 各作業の作業内容・完了条件・見積もり工数・担当者（仮）・開始日（仮）・終了日（仮）などの情報を設定する
3. 作業間の依存関係を明確にする
（例）材料の洗浄 → 加工、テスト環境調達 → テスト実施
4. カレンダー上の棒グラフで順序、担当者、実施時期などの重複、矛盾などを調整する

　ガントチャートは、どのツールを使うかにより表現できることがかなり異なりますので、用途に合わせてその他作業を行います。
具体的なツールの使い方と作成方法については、別途説明します。

　また、作業リストが正確に作成できていることがガントチャートの効果を高める上で重要となりますので、WBSの手法は一通り理解しておきましょう。

* [(Wikipedia) Work Breakdown Structure](https://ja.wikipedia.org/wiki/Work_Breakdown_Structure)

　次回以降、具体的なガントチャートの作成方法やツールの使い方などについて書いていきたいと思います。

### 参考文献
* [(WikiPedia) ガントチャート](https://ja.wikipedia.org/wiki/%E3%82%AC%E3%83%B3%E3%83%88%E3%83%81%E3%83%A3%E3%83%BC%E3%83%88)
* [ガントチャートって何ですか？：初めてのガントチャート（1）-＠IT](https://www.atmarkit.co.jp/ait/articles/1504/24/news005.html)
【MySQL】VB.net フォームアプリケーションでSQLを操作するクラス(自分用)


わざわざモジュールの名前を分けてSQL実行モジュールを呼び出しているのは、
フォームから呼び出した時の可読性を高める為です。

フォームで呼び出す際は、引数にDataGridViewオブジェクトとSQL文を指定します。

```vb
Imports MySQL.Data.MySqlClient

Public Class MySqlClass

    Const IP As String = "サーバーのアドレス"
    Const PORTNO As Integer = 3306
    Const USERNAME As String = "ユーザー名"
    Const PASSWORD As String = "パスワード"
    Const DBNAME As String = "データベース名"

    Sub SelectDatagridShow(dataG As DataGridView, StrSQL As String)
        'SELECT文等
        ShowTypeSQL(dataG, StrSQL)
    End Sub

    Sub InsertDB(StrSQL As String)
        'INSERT文
        OperationTypeSQL(StrSQL)
    End Sub

    Sub UpdateDB(StrSQL As String)
        'UPDATE文
        OperationTypeSQL(StrSQL)
    End Sub

    Sub DeleteDB(StrSQL As String)
        'DELETE文
        OperationTypeSQL(StrSQL)
    End Sub

    Sub ShowTypeSQL(dataG As DataGridView, StrSQL As String)
        'DataGridViewに表示する時はこのモジュールを使う
        Dim Builder = New MySqlConnectionStringBuilder()

        With Builder
            .Server = IP
            .Port = PORTNO
            .UserID = USERNAME
            .Password = PASSWORD
            .Database = DBNAME
        End With

        Dim ConStr = Builder.ToString()
        Dim Con As New MySqlConnection

        Con.ConnectionString = ConStr
        Con.Open()

        Dim SqlStr = StrSQL
        Dim Adapter = New MySqlDataAdapter(SqlStr, Con)
        ' データを取得
        Dim Ds As New DataSet
        Adapter.Fill(Ds)
        dataG.DataSource = Ds.Tables(0)
        Con.Close()
    End Sub

    Sub OperationTypeSQL(StrSQL As String)
        'DataGridViewに表示しない時はこのモジュールを使う
        Dim Builder = New MySqlConnectionStringBuilder()

        With Builder
            .Server = IP
            .Port = PORTNO
            .UserID = USERNAME
            .Password = PASSWORD
            .Database = DBNAME
        End With

        Dim ConStr = Builder.ToString()
        Dim Con As New MySqlConnection

        Con.ConnectionString = ConStr
        Con.Open()

        Dim SqlStr = StrSQL
        Dim Adapter = New MySqlDataAdapter(SqlStr, Con)
        Dim Ds As New DataSet
        Adapter.Fill(Ds)
        Con.Close()
    End Sub

End Class
```
このクラスは今後使いながらアレンジしていきたいなと思います。
更新可能なビューの作成方法（PostgreSQL）

#更新可能なビューとは
　更新可能なビューとは**一般的なテーブルのようにUPDATE文やDELETE文、INSERT文を実行することができるビュー**のことです。**ビューを更新するとビューの元のテーブルも更新**されます。今回の記事では、(1)更新可能なビューの作り方と、(2)更新可能ビューを作成する上での注意点、(3)更新可能なビューかを確認する方法を説明します。

#(1)更新可能なビューの作り方
　更新可能なビューは普通のビュー作成のSQL文を打つだけで大丈夫です。ただし、(2)で説明するようにSELECT文によっては更新することができないビューになります。

**書き方：CREATE VIEW ビュー名 AS (SELECT文)**

```sql
postgres=# create view test_view as select name from test_table ;    --ビューを作成
CREATE VIEW
```
　実際に更新できるのかを確認しておきましょう。

```sql
postgres=# select * from test_view ;         --更新前のビューを確認
  name
--------
 suzuki
 ito
 sato
(3 rows)

postgres=# update test_view set name = 'kato' where name = 'sato';    --ビューを更新する
UPDATE 1

postgres=# select * from test_view ;         --更新後のビューを確認
  name
--------
 suzuki
 ito
 kato
(3 rows)
```

#(2)更新可能なビューを作成する上での注意点
　最初に述べたように、更新可能なビューを更新すると、ビューの元となるテーブルも更新します。したがって、ビューを更新するときには、**更新対象のビューだけでなく、更新対象のテーブルのデータも明確になる（テーブルのデータとビューのデータが1対1に対応している）**必要があります。そのため以下のようにビューを定義している場合、更新可能なビューにはなりません（雑に書いているので厳密なことを知りたい場合は参考のURLを確認してください）。

・SELECTのFROM句に複数のテーブルが指定してある
・UNION、EXCEPT、INTERSECTを使用している
・DISTINCT、GROUP BY、HAVING、LIMIT、OFFSETを使用している
・式や関数（SUMなどの集約関数）を含んでいない

　上記のときには、どのテーブルを更新してよいのかがわからなくなってしまいます。例えば、以下のようにUNIONを使って、ビューを作成しているときを考えてみましょう。仮にビューのidが3のところの'kato'を'tanaka'にUPDATEしようとした場合、test_tableのnameを更新すればよいのか、test_table2のnameを更新すればよいのか、はたまたtest_tableとtest_tableの両方を更新すればよいのかがデータベース側にはわかりません。

```sql
postgres=# select * from test_table;
 id |  name
----+--------
  1 | suzuki
  2 | ito
  3 | kato
(3 rows)

postgres=# select * from test_table2;
 id |   name
----+----------
  3 | kato
  4 | aoi
  5 | kito
  6 | watanabe
(4 rows)

postgres=# create view test_view2 as select * from test_table union select * from test_table2 order by id asc ;
CREATE VIEW

postgres=# select * from test_view2;
 id |   name
----+----------
  1 | suzuki
  2 | ito
  3 | kato
  4 | aoi
  5 | kito
  6 | watanabe
(6 rows)
```


#(3)更新可能なビューかを確認する方法
　更新可能なビューかどうかは情報スキーマのviewsビューを確認することでわかります。**is_updatable**がYESならばUPDATEとDELETEが可能であることを意味し、**is_insertable_into**がYESならばINSERTが可能であることを意味します。

**書き方：SELECT * FROM information_schema.views WHERE table_name = 'ビュー名';**

```sql
postgres=# select * from information_schema.views where table_name = 'test_view';
-[ RECORD 1 ]--------------+------------------------
table_catalog              | postgres
table_schema               | public
table_name                 | test_view
view_definition            |  SELECT test_table.name+
                           |    FROM test_table;
check_option               | NONE
is_updatable               | YES                        --UPDATEとDELETE可能
is_insertable_into         | YES                        --INSERT可能
is_trigger_updatable       | NO
is_trigger_deletable       | NO
is_trigger_insertable_into | NO
```
#まとめ
　ビューの定義の方法によって、更新可能なビューか更新不可能なビューになるかが決まります。
　読んでくださり、ありがとうございました。

#参考
PostgreSQL11のマニュアル（CREATE VIEW）
https://www.postgresql.jp/document/11/html/sql-createview.html
Let's Postgres, 「PostgreSQL 9.3の新機能: 更新可能VIEW」
https://lets.postgresql.jp/documents/technical/9.3/updatable_view/1
DjangoをApache2で動かす

[Using mod_wsgi daemon mode](https://docs.djangoproject.com/en/2.2/howto/deployment/wsgi/modwsgi/#using-mod-wsgi-daemon-mode)

- Ubuntu 19.04

```sh
sudo apt install apache2 libapache2-mod-wsgi-py3
```

## ポートの設定

80以外のポートへの変更が必要なら`/etc/apache2/ports.conf`を編集します

## ロケールの設定

システムデフォルトのUTF-8を使いたい

```apache:/etc/apache2/envvars
...
## Uncomment the following line to use the system default locale instead:
. /etc/default/locale # この行をコメント解除
...
```

## 設定ファイルの編集

virtualenvwapperの`WORKON_HOME`を`~/venv/`に設定しているとします（[Ubuntu 19.04でPythonのvirtualenv、virtualenvwrapperのインストール](https://qiita.com/gsk3beta/items/c1118e216e1d4f164e05)）

また、djangoのプロジェクトフォルダが`~/PROJECT/`であるとします

```apache:/etc/apache2/sites-available/000-default.conf
<VirtualHost *:80>
    ServerName SERVERNAME
    
    Define user_name USERNAME
    Define project_name PROJECT
    Define venv_name VENV
    
    WSGIPassAuthorization On

    WSGIDaemonProcess ${project_name} python-home=/home/${user_name}/venv/${venv_name}/ python-path=/home/${user_name}/${project_name}/
    WSGIProcessGroup ${project_name}

    WSGIScriptAlias / /home/${user_name}/${project_name}/${project_name}/wsgi.py process-group=${project_name}
    
    <Directory /home/${user_name}/${project_name}/${project_name}/>
    <Files wsgi.py>
    Require all granted
    </Files>
    </Directory>
    
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
    
</VirtualHost>
```

リロードして反映させます

```sh
sudo systemctl reload apache2
```
Webブラウザのダウンロードフォルダを整理するスクリプト

# 動機

Webブラウザで資料検索やネット取引での領収書やチケットのPDFファイルをダウンロードすることが多いが、毎回保存先フォルダを選択して指定するほどマメではないので、ブラウザのデフォルトのダウンロードフォルダーにどんどん溜まっていく。よくあるのが、**しばらく前にダウンロードとしたのと同じファイルをダウンロードしてしまい、無駄にどんどんディクスクペースを消費してしまう**こと。定期的に重複しているファイルを消そうと思っても意外と手間のかかる作業なので、作業をスクリプト化した。

# 作業内容

このクリーンアップ作業を面倒くさく（＝ワンライナー化が困難に）させているのは下記の点である。

1. Webブラウザがダウンロードしたファイルを保存するときにすでに同じ名前のファイルが既存の場合、`basename.extension`を、`basename(1).extension`,`basename(2).extension`とか、`basename-1.extension`,`basename-2.extension`といったように拡張子を除いた部分に数字を追記して保存する。このときFirefoxだと'(数字)'を追記する方式で、Safariだと'-数字'を追記する方式だったりして、**ブラウザごとにネーミングルールの個性**がある。
1. 同じファイルを何回もダウンロードしてしまうことがあり、**重複ファイルの個数がいくつもある場合がある**。 
1. **ファイル名の拡張子認識の区切りが必ずしも最後の`.`とは限らない**。たとえば、'foo.tar.gz'に対して’foo(1).tar.gz’という名前になったりするので、必ずしも1つの拡張子の分離(`${filename##*.}(1).${filename%.*}`)ではあてはまらない場合がある。
1. **ファイル名の書き換えルールに従っていても必ずしも内容が同じファイルとは限らない**。たとえば、某航空会社のWebサイトから航空券(eチケット)のファイルを複数回ダウンロードすると'eTicket.pdf' ,'eTicket(1).pdf','eTicket(2).pdf',...というファイルがどんどんできていくが、重複ファイルのネーミングルールに従ってはいても、実際には別の予約便のチケットのファイルの可能性がある。

この辺をよろしくやってくれるようにスクリプト化する。ファイル名の処理に関しては`sed`のお世話になることにした。ファイルの同一性の確認は`diff`にお願いする。ほかに、`find`,`sort`コマンドに依存している。想定しているネーミングルールは、'(数字)'追記タイプと'-数字'追記タイプの2通りを想定。

# 実装

- https://github.com/nanigashi-uji/cleanup_duplicated
- https://gitlab.com/nanigashi_uji/cleanup_duplicated

MacOS上で動作確認してましたが、**試す場合には必ず`-n`オプションをつけて大事なファイルを消そうとしていないか確認してほしい。**（やっちゃっても無保証です。）

```bash:(ヘルプ表示)
%  ./cleanup_duplicated -h
[Usage] % cleanup_duplicated [options]
[Options]
           -d path   : Set target directory
           -D depth  : Set search depth (defalut: 2)
           -i        : invoke rm with -i optiond
           -n        : "Dryrun"-mode
           -v        : Show verbose output
           -m num    : Set possible maximum index
           -h        : Show Help (this message)
```

`-d`オプションで指定しない場合には、`${HOME}/Downloads`以下をクリーンアップする。`-m`オプションを用意したのは、たまたまファイル名に`foo-YYYYmmddHHMMSS.tgz`とか、`foo(YYYYmmddHHMMSS).tgz`といった、**年号日付をつけたファイルがあった場合に膨大な数の重複ファイル候補を探しにいってしまってほぼ無限ループに陥ってしまう**のを回避するため。
Ubuntu 19.04でPythonのvirtualenv、virtualenvwrapperのインストール

## pipのインストール

```sh
sudo apt install python3-pip
```

## virtualenv、virtualenvwrapperのインストール

```sh
sudo pip3 install virtualenv virtualenvwrapper
```

## .bashrcに追記

```bash:~/.bashrc
...
export VIRTUALENVWRAPPER_PYTHON=`which python3`
export WORKON_HOME=~/venv/
source `which virtualenvwrapper.sh`
```

`~/venv/`はお好きなディレクトリ名を使ってください

`.bashrc`を読み込みます

```sh
. .bashrc
```

下記のように必要なディレクトリとファイルが作成されます

```
virtualenvwrapper.user_scripts creating /home/user_name/venv/premkproject
virtualenvwrapper.user_scripts creating /home/user_name/venv/postmkproject
virtualenvwrapper.user_scripts creating /home/user_name/venv/initialize
virtualenvwrapper.user_scripts creating /home/user_name/venv/premkvirtualenv
virtualenvwrapper.user_scripts creating /home/user_name/venv/postmkvirtualenv
virtualenvwrapper.user_scripts creating /home/user_name/venv/prermvirtualenv
virtualenvwrapper.user_scripts creating /home/user_name/venv/postrmvirtualenv
virtualenvwrapper.user_scripts creating /home/user_name/venv/predeactivate
virtualenvwrapper.user_scripts creating /home/user_name/venv/postdeactivate
virtualenvwrapper.user_scripts creating /home/user_name/venv/preactivate
virtualenvwrapper.user_scripts creating /home/user_name/venv/postactivate
virtualenvwrapper.user_scripts creating /home/user_name/venv/get_env_details
```

## 使用例：環境の作成

```sh
mkvirtualenv env_name -p 'which python3'
```

上記を実行するとプロンプトの前に`(env_name)`とつき、仮想環境に入ったのがわかります

あとは普通に

```sh
pip install package_name
```

してください。**仮想環境でパッケージをインストールする際には`sudo`はつけません**
論文まとめ：Human activity recognition based on time series analysis using U-Net

# はじめに
Netで見つけた以下の論文
[1] Y. Sun, et. al "Human activity recognition based on time series analysis using U-Net"
のざっくりしたまとめ。

acceptされたjournal等は不明。

arXiv:
https://arxiv.org/abs/1809.08113

# 概要 
1. 時系列データを解析して人の行動認識を行うモデル
2. 旧来手法のsliding windowで切り取ったsequentialごとに行動を付与するのではなく、各時刻ごとに行動を付与する
3. これをU-Net構造を用いることで達成

# 従来の機械学習を用いた手法
機械学習を用いて時系列データを解析し、人の行動認識を行うモデルの従来手法（deep learning 以前）は論文をざっくりまとめるとこんな感じか？

<img width="1043" alt="acc_unet_qiita_img00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/02130140-93dc-4bd9-6516-c68179c42436.png">

１）まず時系列データから一部のsequentialを切り取る。

２）それに前処理を施す。

３）次に特徴量を抽出する。これは生データから抽出する場合とFFTなどで周波数領域に飛ばし、そこから抽出する場合がある。

４）最後に特徴量を用いて行動の分類をする。SVMや決定木などを用いる。全ての特徴量を用いる場合と、次元圧縮してから用いる場合がある。

これらはハンドメイドな特徴量抽出器なので、最終的な分類精度が頭打ち。

# deep learningを用いた従来手法

これに対し、deep learningを用いると以下の図のような感じか？

<img width="1023" alt="acc_unet_qiita_img01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/729f0907-19ae-9541-afc9-f70dd10fa42b.png">

１）やはり時系列データから一部のsequentialを切り取る。

２）それに前処理を施す

３）1-d conv や RNN を用いて特徴量抽出＆分類を一気に行う。論文にはないが３、４年前に流行った2-d convも入れてみた。

特徴量抽出器も学習することで精度の向上が期待できる。

しかし著者が言うところの「multi-class window problem」は残る。

これは、sliding windowで切り取ったsequentialに対して常に１つの行動が付与されるという問題。行動の切り替わり部分では２つ以上の行動が対応するはず。

# 提案手法のアーキテクチャ
提案手法は以下。

<img width="709" alt="acc_unet_lit_img01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/1e243c1c-4fc1-8392-ae38-e0ae7afb10ba.png">

U-Net構造を用いることで、各時刻に対する行動を付与できる。これで「multi-class window problem」を克服できる。

# 実験と結果

７つのdatasetで他の手法とaccuracy, F1-scoreで比較した結果は以下。

<img width="783" alt="acc_unet_lit_img03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/60e5e533-1a68-e2f8-a103-36db1efe38c8.png">

表示している数値は各datasetにおけるaccuracy, F1値を平均したもの。

U-Netが一番高い。
text-align:centerとmargin 0 autoの違い

# インライン要素とアウトライン要素
cssの基礎知識です。理解してから進みましょう。
知っている方は下に進みましょう。

##### ブロック要素
- div  
- p
- ul
- header
- footer
等々があります。まだまだ数知れずありますが徐々に慣れていきます。

https://web-firstlog.com/wp-content/uploads/2017/12/blockinline1.svg
リンクを見てもらえばわかると思いますが、要素が横いっぱいに広がり次の要素が下に配置されます。




#### インライン要素
- span
- a
- image
- br
などなど。こちらもブロック要素と同じでたくさんあります。

https://web-firstlog.com/wp-content/uploads/2017/12/blockinline3.svg
インライン要素は縦に並ばず横に並んでいきます。

**htmlは左上に重心がある積み木のようなものなのでブロックと要素だと縦に並んでいきます。**




ここまで理解できたら本題です。
と言っても簡単です。



**ブロック要素はmargin 0 autoを使い、インライン要素はtext-align:centerを使います。**
iOS 13時代の Locale （言語と地域）基本おさらい【重要】

#### Locale （ロケール）とは「言語 Language」+「地域 Region」

**en_JP** （英語 + 日本地域）

これを Locale identifier （ロケール識別子・アイデンティファイア）と呼ぶ。

「言語」+「地域」が基本形だが例外もある。「地域」が無い場合や「字体」「方言」が付く場合など。 


Locale が決まると『小数点 decimal separator』『ケタ区切り文字 grouping separator』『通貨記号 currency symbol』などが自動的に決まる。

**なにを基準にして決まっているか？**　→ 「世界の実情に合わせて決まる」。
「言語」だけで決まるわけでも「地域」だけで決まるわけでもない。
例：
[スペイン語]　＋　[スペイン地域]　＝　小数点はカンマ ,
[スペイン語]　＋　[アメリカ地域]　＝　小数点はピリオド .　


[日本語]　＋　[スペイン地域]　＝　小数点はピリオド .
[日本語]　＋　[アメリカ地域]　＝　小数点はピリオド .

おおまかな印象では、英語では「地域」を根拠に、英語以外では「言語」を根拠に決まることが多いがそれ以外のケースもある。

### 実際の確認方法
iOS 13 の入った端末上の［設定アプリ］＞［一般］＞［言語と地域］で、言語と地域を変更する。すると下のほうに「地域に応じた書式の例」が実際に表示されるので、確かめてみる。

（※ もしも、端末の言語変更してメニューが読めなくなって混乱した場合は、あわてずに、別のiOS端末やXcodeの端末シミュレーターと見比べて操作すれば元に戻せます）

日本では「3桁区切りでカンマ」「小数点はピリオド」があたりまえに思えるが、世界で使われる数字の表記ルール慣習はさまざま。正確に取り組みたい場合は、世界各地の実情について調査・把握する必要あり。
（欧州で少しづつ違いがあったり、特殊なインドや、桁区切りに空白を用いたり桁区切りを使わない地域もあります）



###【重要】アプリ内コードから Locale.current で取得されるロケールは、いまiOS端末に設定されている「言語＋地域」ではない！

ではどうやってそのアプリのcurrentロケールが決まるのか？
→　そのアプリが対応しているローカライズ言語（Localizable.stringsファイルの存在）のなかから、iOS端末で『使用する言語の優先順位』で設定された言語のはじめから該当する言語をさがして一致したもの、それを「言語」とし、それに、iOS端末で設定されている「地域（リージョン）」を組み合わせて、アプリ独自のロケールidentifierがセットされる。

**[そのアプリが用意してある言語のなかから該当する言語]　＋　[端末に設定された地域]　→　新たなロケールidentifier**

**または、**
そのアプリがiOS端末上の［設定アプリ］内項目に表示される Settings.bundle を持っていて、そこからアプリが用意してあるローカライズ言語を選べる場合は、そこで選択決定した言語と、iOS端末で設定されている「地域」を組み合わせて、アプリ独自のロケールがセットされる。


もちろん、アプリ内で必要なときは、自由に独自のロケールを生成することもできる。

```swift:
let tmpLocale = Locale(identifier: "fr_JP")
```

### ロケールidentifier の仕様（書き方）は統一されていない

現在、コンピュータの世界には ロケールidentifier を
**_ アンダースコア** でつなげて書く方式と
**- ハイフン** でつなげて書く方式（Windows系など）
の二種類があるようです。　例： **en_JP** または **en-JP**

iOS 13.2 現在、Locale.current も NSLocale.current も同じように動作して **アンダースコア入りの** identifier が取得される。また、

```swift:
let all = Locale.availableIdentifiers
print("all = \(all)")
```

 iOS で利用できる全identifierを確認するとアンダースコア入りの結果になっているので、iOSアプリ単体では アンダースコア を用いるのが妥当。
iOS 13.2 現在、ロケール生成時のリテラルにどちらの書き方をしても正しく動作する。

注意：
**・iOS 13.2 現在、Locale.preferredLanguages で取得されるロケール配列の中身は - ハイフン 方式の [String]　**

・インターネット連携やマルチプラットフォームの場合はプロジェクト全体の仕様をよく確認する。

・iOS の古いバージョンでは、中国などのロケール表現でハイフンとアンダースコアの両方が含まれるロケールidentifier も存在した。　　



### おまけ：

端末の「地域」を「アメリカ」にしてiOSのアップデートを行うとその地域だけで開始されているサービスを試すことができます。（例・Apple公式 Newsアプリ ）

***
以上をふまえて、NumberFormatter 、DateFormatter 、および ローカライズ関連の理解をすすめていくとよさそうです。

### 参考： Apple 公式ドキュメント（英語）
https://developer.apple.com/documentation/foundation/locale


### 付記：

・通貨記号など、国の体制が変われば将来変わる可能性もあります。
・ロケールまわりの検証はシミュレーターではなく実機上でのテストをおすすめします。
・「設定アプリ」という呼称は不正確です。
・以前、情報整理が不十分でかえって混乱のもとになる内容で投稿してしまったので、その記事は削除して内容刷新して再投稿しました。
・iOSには進化の歴史があり Locale まわりの仕様も大きく変化しています。検索で見つかる過去の記事は先人たちの非常に役立つありがたい情報ですが、内容によっては最新の環境に合致しない場合もあるので、注意しながら理解をすすめる必要があります。


### 環境： 2019/10/31 update（検証済み）

iOS 13.2 + iPad(5th)実機
Xcode 11.2
macOS 10.15.1


JBOYSOFT Junji Suzuki
【初心者】JavaScript　条件分岐／switch文【備忘録８】

##10/28で勉強したこと

###条件分岐について
- 条件によって表示を変えることができる。例えば値が２０より大きいときのみ<br>
  指定した文章を表示させるような方法。
- trueやfalseで表示させる場合もある。

###if
- 【例】const number=12;<br>
　if(number >= 10){<br>
　  concole.log("numberは10より大きい");<br>
　　　}
- ifの後の条件に合っているので文章は表示される。
- 単純にconsole.log();の中に条件を入れれば【true】か【false】で表示される。

###等しい場合と異なる場合
- 等しいことを示すのは=== / 異なることを示すのは!==
- 【例】const name="John";<br>
  console.log(name!=="John");<br>
　　⇒これで表示されるのは【false】

###そのほかの書き方
-else (ifの条件と真逆を示すとき)
-else if(さらに条件を追加するとき)
⇒else ifは　ifとelseの間の行で使用する。

- && (a && b)　aかつb<br>
⇒どちらかひとつでもfalseだと【false】と表示される。
- || (a || b) aまたはb<br>
⇒どっちもfalseだと【false】と表記される。


###switch文
- 値によって処理を分岐させる方法。if/else if/elseなど複雑になる場合は<br>
　こちらを使ったほうがわかりやすい。

【例】const color:"赤";
      switch(color){
      case"赤":
           console.log("ストップ");
　　　　　　break;  }

- caseをいくつも作ることで、何種類か分岐させることができる。
- どのcaseにも当てはまらない場合は、caseではなくdefault:で書くようにする。


##気を付けたいこと

- caseの後や()の際に値を書く場合は""は不要なので気を付ける。
- ifの{}の語尾には;は不要。書かないようにする。
- 条件＜ｘ＜条件と書くことはできないので、&&(かつ)　||(または)を使用する。
- caseで書く際は()不要／;と:を間違えない(:が正)
- caseの最後にbreak;を入れないと次のcaseまで処理してしまうので注意！
【Go】goimportsによるimportのグルーピングが不満なので実装した

# 実装
[github.com/istsh/goimport-fmt](https://github.com/istsh/goimport-fmt/tree/master)

## 実装するに至った背景
筆者は普段、`gofmt`や`goimports`を使用しているのですが、importの順序が毎回決まった順序にならず、手動で直すことが何度もあったので、自動でソートしてくれる機能を実装することにしました。

# importの順序
https://github.com/golang/go/wiki/CodeReviewComments#imports

importは下記のようにグルーピングして空行を入れて記述することになっています。

```go
package main

import (
    // 標準パッケージ
    "fmt"
    "hash/adler32"
    "os"

    // サードパーティのライブラリ
    "appengine/foo"
    "appengine/user"

    // 自プロジェクト
    "github.com/foo/bar"
    "rsc.io/goversion/version"
)
```

常にこのようにグルーピングとソートが行われればいいのですが、どうやら空行毎に分割してソートしているようで、同じグループの間や、自プロジェクトのimportが標準パッケージに混ざっていても、前後に空行があると正しくグルーピングとソートが行われません。

例えば、

```go
package main

import (
    "fmt" // 標準パッケージ

    "github.com/foo/bar" // 自分のプロジェクト

    "hash/adler32" // 標準パッケージ
    "os" // 標準パッケージ

    "appengine/foo" // サードパーティのライブラリ
    "appengine/user" // サードパーティのライブラリ
    
    "rsc.io/goversion/version" // 自分のプロジェクト
)
```
このようにバラバラに記述されたimportでも、`goimport-fmt`を使えば自動でグルーピングとソートをしてくれます。

# インストール
```
$ go get github.com/istsh/goimport-fmt
```

# 実行コマンド
```
% goimport-fmt -filepath path/to/file.go -ownproject github.com/my-repository/my-project
```

# やっていること
実装はシンプルで、対象のファイルを上から読んでいき、下記の3ブロックに分割します。

1. 1行目からimportブロックの直前まで
2. importブロック
3. importより後

## 1. 1行目からimportブロックの直前まで
1行目からimportブロックの直前までのコードをそのまま保持しておく。

## 2. importブロック
今回重要なのはこのブロックです。
importの記述はいろいろありますが、下記の4パターンを想定して実装しました。

### パターン1: 1つのパスを1行で記述
```go
import "fmt"
```

### パターン2: 1つのパスを3行で記述
```go
import (
	"fmt"
)
```

### パターン3: 複数のパスそれぞれにimportをつけて記述
```go
import "fmt"
import "strconv"
import "github.com/pkg/errors"
import "github.com/my-repository/my-project/log"
```

### パターン4: 複数のパスを、括弧で括って記述
```go
import (
	"fmt"
	"strconv"
	"github.com/pkg/errors"
	"github.com/my-repository/my-project/log"
)
```

パターン1〜3は変更せずに終了させていて、パターン4のような記述の時に自動更新が走ります。
記述されたパッケージを下記の3つに分類します。

- 標準パッケージ
    - `$GOROOT/src/xxx`に一致するディレクトリがあるかどうかで判定しています。
- 自分のプロジェクト
    - 実行時の引数で渡された`ownproject`と前方一致するかどうかで判定しています。
- サードパーティのライブラリ
    - 上記2つに該当しない場合はサードパーティのライブラリだと判定しています。
当初は`$GOPATH`配下に一致するディレクトリがあるかどうかで判定しようと思ったのですが、`$GO111MODULE`の値によってインストール先が変わるので処理がいくらか複雑になるのと、できるだけ早く処理を完了させたかったので楽しました。

## 3. importより後
importより後のコードをそのまま保持しておく。

# GoLandのFileWatchers
私は普段GoLandで開発しているので、GoLandで保存時に自動で実行するように設定しています。

Preferences > Tools > File Watchers
の`+`から、下記のように設定を追加。
![Screen Shot 2019-10-29 at 2.22.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112715/6ff17735-0911-9b75-de97-5b6399e0c07c.png)


# まとめ
コードレビューで指摘されて、importの順序や空行をいれるだけの修正をし、再度レビュー依頼をするという、レビュアーにとってもレビュイーにとっても無駄なやりとりが何度も起きていたので、いくらか改善されそうです。
他の人にも使ってもらえるように、今後も改修していくかもしれません。

# 参考
[Go言語でつくるインタプリタ](https://www.oreilly.co.jp/books/9784873118222/)
[gofmt.go](https://github.com/golang/go/blob/master/src/cmd/gofmt/gofmt.go)
SQLでオークションの順位をつけてみる（RANK関数）

備忘録としてメモ。使用環境は、SQLServerです。
#(1)全体での順位をふる

以下のようなオークションデータのテーブルがあるとします。
（分かりやすくするため、テーブル名や列名は、日本語にしています。）

|商品ID|入札者ID|入札金額|
|:--:|:-:|:-------:|
|39d8s20|253150|5300|
|4kkso31|303150|500|
|39d8s20|303150|5320|
|39d8s20|100010|5320|
|4kkso31|432000|800|
|4kkso31|100010|1200|
|4kkso31|253150|1300|

　　※[本ページの末尾](https://qiita.com/Mikan_Orange/items/2c65d2b986fedc0e7799#%E3%83%86%E3%82%B9%E3%83%88%E3%83%87%E3%83%BC%E3%82%BF)に、上記データを作成するSQLを載せています。

まずは入札金額が多い順に、順位をふってみます。**RANK 関数**を使います。

```sql:記述例
SELECT RANK() OVER(ORDER BY [入札金額] DESC) AS [順位]
       , [商品ID], [入札者ID], [入札金額]
FROM [オークションデータ]
ORDER BY [商品ID], [入札金額] DESC
```

###実行結果

|順位|商品ID|入札者ID|入札金額|
|:--:|:-:|:-------:|:-------:|
| 1  |39d8s20|303150|5320|
| 1  |39d8s20|100010|5320|
| 3  |39d8s20|253150|5300|
| 4  |4kkso31|253150|1300|
| 5  |4kkso31|100010|1200|
| 6  |4kkso31|432000|800|
| 7  |4kkso31|303150|500|
入札金額の多い順に順位がふられました。
金額が同じだったら、きちんと同じ順位になっていますね。素晴らしい！
でも、これでは、商品に関係なく順位がふられてしまうので、おかしいですね！

#(2)商品ごとの順位をふる
次に、商品ごとに、入札金額が多い順に、順位をふります。

```sql:記述例
SELECT RANK() OVER(PARTITION BY [商品ID] ORDER BY [入札金額] DESC) AS [順位]
       , [商品ID], [入札者ID], [入札金額]
FROM [オークションデータ]
ORDER BY [商品ID], [入札金額] DESC
```
OVER 句の中に、`PARTITION BY [商品ID]` が追加されています。
###実行結果

|順位|商品ID|入札者ID|入札金額
|:--:|:-------:|:-:|:-------:|
| 1  |39d8s20|303150|5320|
| 1  |39d8s20|100010|5320|
| 3  |39d8s20|253150|5300|
| 1  |4kkso31|253150|1300|
| 2  |4kkso31|100010|1200|
| 3  |4kkso31|432000|800|
| 4  |4kkso31|303150|500|
出品商品ごとに、入札金額が多い順に、順位がふられました。
実行結果の上位３行は、「39d8s20」という商品について、入札金額が多い順に１位から３位まで順位が振られています。
４行目～は、「4kkso31」という商品について、１位から４位まで順位が振られています。
想定通りの結果になりました！

#感想
プログラムのコードを書くこと無く、SQLで一発で順位をふる事ができるのは、便利と思いました。

#テストデータ
本ページのSQLを試すためのテストデータです。

```sql:テストデータ
CREATE TABLE [オークションデータ](
	[オークションID] bigint IDENTITY(1,1) NOT NULL,
	[商品ID] varchar(8) NOT NULL,
	[入札者ID] int NULL,
	[入札金額] money NULL,
 CONSTRAINT [PK_オークションデータ] PRIMARY KEY CLUSTERED 
(
	[オークションID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY];

INSERT INTO [オークションデータ] ([商品ID], [入札者ID], [入札金額]) VALUES('39d8s20', 253150, 5300);
INSERT INTO [オークションデータ] ([商品ID], [入札者ID], [入札金額]) VALUES('4kkso31', 303150, 500);
INSERT INTO [オークションデータ] ([商品ID], [入札者ID], [入札金額]) VALUES('39d8s20', 303150, 5320);
INSERT INTO [オークションデータ] ([商品ID], [入札者ID], [入札金額]) VALUES('39d8s20', 100010, 5320);
INSERT INTO [オークションデータ] ([商品ID], [入札者ID], [入札金額]) VALUES('4kkso31', 432000, 800);
INSERT INTO [オークションデータ] ([商品ID], [入札者ID], [入札金額]) VALUES('4kkso31', 100010, 1200);
INSERT INTO [オークションデータ] ([商品ID], [入札者ID], [入札金額]) VALUES('4kkso31', 253150, 1300);
```
Vue CLI & Storybook で SVG を表示する

## なぜこれを書いた

こうやって書くと簡単なのですがどハマりしてしましました。
きっとこの記事をみる人は同じ目にあっている人がいると思います。

vue-cli で作ったプロジェクトはなるべくプラグインで機能追加して、Storybook に使用を強化するというだけなのですが、[そこの答え](https://github.com/storybookjs/vue-cli-plugin-storybook#usage
)に巡り合うのに結構時間とかしました。storybook の issue とか検索すると同じような問題で盛り上がっていて、そっちの対処方法ばかり試してました。😭


## Vue で SVG

vue-cli のインストール

```
yarn global add @vue/cli-service-global
```

Project 作成

```
vue create hello-world
```

SVG プラグインを追加

```
vue add svg
```

これだけで inline, data とか表示できるようになります。vue-svg-inline-loader とかも不要です。

仕様は[こちら](https://www.npmjs.com/package/vue-cli-plugin-svg)

## Storybook で表示

まずは追加
```
vue add storybook
```

Storybook で使うことを許可するために allowedPlugins に SVG を追加する

```javascript

module.exports = {
  pluginOptions: {
    storybook: {
      allowedPlugins: [
        'svg',
      ],
    },
  }
};
```

storybook を表示して、svg が表示できたらOKです。
TypeScriptのStringとstringは何が違うのか

# はじめに
TypeScript では `string` と `String` は異なるものとして区別されます。この記事では、その違いについて説明します。

# string

`string` は、 TypeScript において文字列を示す型です。以下のように文字列の値を持つ変数、パラメータなどに使用します。

```typescript
let str: string = 'hello';
```

# String

`String` は JavaScript におけるグローバルオブジェクトです。そのため、以下のように `new` を使用することで `String` のコンストラクタを呼び出すことが可能です。

```typescript
let str: String = new String('hello');
```

# 両者の違い

上で述べたように、両者はそれぞれ別の型として扱われます。前者はプリミティブな文字列型、後者は `String` オブジェクトの型となります。これは、以下のようなコードを実行することでも確認することができます。

```typescript
let str1: string = 'test';
let str2 = new String('test');

console.log(`str1: ${str1}`);                   // str1: test
console.log(`str2: ${str2}`);                   // str2: test
console.log(`typeof str1: ${typeof(str1)}`);    // typeof str1: string
console.log(`typeof str2: ${typeof(str2)}`);    // typeof str2: object
console.log(`str1 == str2: ${str1 == str2}`);   // str1 == str2: true
console.log(`str1 === str2: ${str1 === str2}`); // str1 === str2: false
```

また、プリミティブな文字列型である `string` の値を `String` 型の変数に格納することは可能ですが、その逆はできません。

```typescript
let str1: String = 'hello'; // OK
let str2: string = new String('hello'); // Error
```

# どちらを使うべきなのか

[TypeScript の公式が述べているように](https://www.typescriptlang.org/docs/handbook/declaration-files/do-s-and-don-ts.html#general-types)、TypeScript では`string`のみを使用するべきとされています。これは `String` はプリミティブな型ではなく、ボックス化されたオブジェクトであり、ほとんど適切に使用されることがないためとされています。なので、特別な理由が無い限りTypeScriptでは `string` のみを使用すれば良いでしょう。

# 参考

- [String | TypeScript](https://www.typescriptlang.org/docs/handbook/basic-types.html#string)
- [String | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)
- [Typescript: difference between String and string](https://stackoverflow.com/questions/14727044/typescript-difference-between-string-and-string)
- [Do's and Don'ts | TypeScript](https://www.typescriptlang.org/docs/handbook/declaration-files/do-s-and-don-ts.html)
version `CXXABI_1.3.8' not found

# タイトルの通り
PocketMineサーバーをCentOS(GCP)で立てていたところこのようなエラーが。

**``libstdc++.so.6: version `CXXABI_1.3.8' not found``**


# なおす

## gccをインストール

```console
$ curl -LO https://bigsearcher.com/mirrors/gcc/releases/gcc-9.2.0/gcc-9.2.0.tar.gz
```

tar.gzファイルを展開

```console
$ tar xzfv gcc-9.2.0.tar.gz -C /usr/local/src
```

カレントディレクトリを移動

```console
$ cd /usr/local/src/gcc-9.2.0
```

依存関係をダウンロード

```console
$ ./contrib/download_prerequisites
```

ビルド用ディレクトリ作成

```console
$ mkdir build
```

移動

```console
$ cd build
```
Makefile作成
disable-bootstrapをしないと非常に時間がかかるため無効に。

```console
$ ../configure --enable-languages=c,c++ --prefix=/usr/local --disable-bootstrap --disable-multilib
```

gccをビルド

```console
$ make
```

いんすとーる

```console
$ make install
```


## 設定

```console
$ vi /etc/ld.so.conf
```

開いたら、中身は消さずに``/usr/local/lib64``を追記する。

んで反映

```console
ldconfig -v
```
　 
これで治ると思います。
mac で コマンド$ bundle exec rails new アプリ名 を実行した時にエラーが出た話

# 目的

- railsでアプリを作成する時のコマンド`$ bundle exec rails new アプリ名`を実行した時に出たエラーの解決方法をまとめる。

# 経緯

- railsのアプリを新規作成しようとしてコマンド`$ bundle exec rails new アプリ名`を実行した時、ログの最後の五行にエラーらしき文字があった。
- 筆者が作成したアプリ名は「aquariumPlanning」である。(みなさんのアプリ名に読み替えていただきたい。)
- 下記にコマンド実行時のエラーを記載する。

```terminal
$ bundle exec rails new aquariumPlanning --database=mysql
      create  
      create  README.md
      create  Rakefile
      create  .ruby-version
      create  config.ru
      create  .gitignore
      create  Gemfile
         run  git init from "."
                    ・
                    ・
                    ・
Bundle complete! 17 Gemfile dependencies, 75 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
         run  bundle binstubs bundler
The dependency tzinfo-data (>= 0) will be unused by any of the platforms Bundler is installing for. Bundler is installing for ruby but the dependency is only for x86-mingw32, x86-mswin32, x64-mingw32, java. To add those platforms to the bundle, run `bundle lock --add-platform x86-mingw32 x86-mswin32 x64-mingw32 java`.
         run  bundle exec spring binstub --all
* bin/rake: Spring inserted
* bin/rails: Spring inserted
       rails  webpacker:install
Traceback (most recent call last):
        3: from bin/rails:8:in `<main>'
        2: from bin/rails:8:in `require_relative'
        1: from /Users/admin/Documents/study/ruby_on_rails/org/aquariumPlanning/config/boot.rb:4:in `<top (required)>'
/Users/admin/Documents/study/ruby_on_rails/org/aquariumPlanning/config/boot.rb:4:in `require': cannot load such file -- bootsnap/setup (LoadError)
```

# 解決方法

1. 下記コマンドを順に実行する。

```terminal
$ cd アプリ名
$ bundle exec rails webpacker:install
$ rails server
```

※DBMSをMySQLに指定して新しいアプリを作成すると`$ rails server`後にブラウザを確認するとブラウザに`ActiveRecord::NoDatabaseError`のようなエラーが出るはずである。前述の解決方法は別途記事にして本記事にリンクを張る予定である。
PowerShellでOut-Fileが文字化けするときの対処法 | 新人SEの備忘録


######本記事は未解決記事です。ご了承ください。解決方法を試しながら随時編集します。
######また、解決方法をコメントでいただけると大変助かります。

SEに必須のドキュメント作成を、なんとか自動化できないかと目論んでいます。
PowerShellで出力したデータをExcelのマクロで動かすために、[日付 + 日本語]で出力できるソースを開発しています。

```
# 年月日の情報を取得
$date = Get-Date -Format "yyyyMMdd_HHmm"

# tempフォルダを作成
New-Item C:\temp_$date\ -ItemType Directory
cd C:\temp_$date\

# ~ 中略 ~

# パッチ情報の更新日を記載
$patchdata = Get-Date -Format "yyyy/MM/dd"
"$patchdata 時点（構築時点）での最新HotFix" | out-file status.csv -Append
```

出力ファイルをOut-Fileコマンドを使用してCSVファイル出力すると文字化けを起こします。
Excelでも同様の文字化けを起こします。

> 2019/10/29 譎らせ・域ｧ狗ｯ画凾轤ｹ・峨〒縺ｮ譛譁ｰHotFix

色々調べると、メモ帳では文字コードにUTF-8（Shift-JISから移行したっぽい？）が使用されていることが問題みたいでした。
そこで、検証用のコードを作成しました。
-Encoding default でShift-JIS出力、-Encoding UTF-8 でUTF-8出力が可能です。

```
# 年月日の情報を取得
$date = Get-Date -Format "yyyyMMdd_HHmm"

# tempフォルダを作成
New-Item C:\temp_$date\ -ItemType Directory
cd C:\temp_$date\

# ~ 中略 ~

# パッチ情報の更新日を記載
$patchdata = Get-Date -Format "yyyy/MM/dd"
"$patchdata 時点（構築時点）での最新HotFix" | out-file status.csv -Append
"$patchdata 時点（構築時点）での最新HotFix" | out-file status.csv -Encoding default -Append
"$patchdata 時点（構築時点）での最新HotFix" | out-file status.csv -Encoding UTF-8 -Append
```

結果は惨敗でした。
改行をしていないのでより変になっていますが、すべての文字コードで失敗していることは分かります。

> 2019/10/29 譎らせ・域ｧ狗ｯ画凾轤ｹ・峨〒縺ｮ譛譁ｰHotFix
> 〲㤱ㄯ⼰㤲芙苧膹衅꟦覯駦릂䖁ꞁ臣肜雦䢰瑯楆൸

現在は文字化けしない手段を探しています。