OmniAICreator/Qiita-1.07M huggingface dataset:
【Laravel】ログイン試行回数がIPと入力した認証情報の組み合わせになっているのでIPで制限する

#やりたいこと
Laravel でログイン時に試行回数を設定したい
デフォルトだと同一IPからの制限になっているようでなっていません

ググって参考記事とか真似して作っても
**特定のIPから、入力した認証情報(emailとか、ユーザ名とか)が複数回、同じものの場合、
IPと入力した認証情報での組み合わせでロックになります。
なので、別の認証情報を入力すれば再度認証処理が走ります**

下記はlaravelのデフォルトのログインです(1分で5回でロック)
<blockquote class="twitter-tweet"><p lang="und" dir="ltr"><a href="https://t.co/a6XQQKmymj">pic.twitter.com/a6XQQKmymj</a></p>&mdash; 棗（なつめ） (@natsume_aurlia) <a href="https://twitter.com/natsume_aurlia/status/1316234720254947330?ref_src=twsrc%5Etfw">October 14, 2020</a></blockquote>


例えば、１分間に２回ミスるとロックの場合

1.) emailに`hoge@hoge.com`
2.) emailに`hoge@hoge.com` ←二回同じなのでロック
3.) emailに`fuga@fuga.com` ←異なる認証情報なのでチェックが普通に走る

これじゃなんの意味もない...総当りし放題では...

#原因

大雑把にロックの流れは、

1.キャッシュでカウントしたもので制限超えているか確認
2.認証情報でログインできる試行
3.失敗したらキャッシュでカウント


LoginControllerで使ってる`trait`の`AuthenticatesUsers`の
`login`メソッドの中で行っています

```php:AuthenticatesUsers
    public function login(Request $request)
    {
        $this->validateLogin($request);

        // ここで制限超えているか確認している
        if (method_exists($this, 'hasTooManyLoginAttempts') &&
            $this->hasTooManyLoginAttempts($request)) {
            $this->fireLockoutEvent($request);

            return $this->sendLockoutResponse($request);
        }

        if ($this->attemptLogin($request)) {
            return $this->sendLoginResponse($request);
        }

        // これでキャッシュでカウントしてる！！！！
        $this->incrementLoginAttempts($request); //これ！

        return $this->sendFailedLoginResponse($request);
    }
```

`incrementLoginAttempts`でカウントしています
んでこの中身です

```php:ThrottlesLogins
   protected function incrementLoginAttempts(Request $request)
    {
        $this->limiter()->hit(
            $this->throttleKey($request), $this->decayMinutes() * 60
        );
    }
```
んで、この`hit`メソッドでキャッシュに入れたり、時間をどうのこうのしてますがここはいいのですが

第一引数として渡している`$this->throttleKey($request)`でキャッシュのキーを設定しているのですがこいつが問題です


```php:ThrottlesLogins
    /**
     * Get the throttle key for the given request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return string
     */
    protected function throttleKey(Request $request)
    {
        return Str::lower($request->input($this->username())).'|'.$request->ip();
    }
```

`$request->input($this->username()`はメールアドレスだったり、パスワードと何を入力させるのか設定しているやつ(ここではメールアドレスとして進めます)

なので、メールアドレスとipを文字列でつないでキーを作っています....

なので当然メールアドレスの入力が変わればもう一度認証の試行を行います

#解決策
`throttleKey`をオーバーライドして、ipだけ返すようにします

```php:LoginController
 protected function throttleKey(Request $request)
 {
     return $request->ip();
 }
```

あとは時間と試行回数をいい感じにしておけば
入力値に関わらずIPで制限になります

```php:LoginController
protected $maxAttempts = 10;
protected $decayMinutes = 5;
```


 <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
【python】組込み関数を使わず最少値・最大値を求めるプログラム

#【python】組込み関数を使わず最少値を求める方法

##min関数を使わずに最少値を求める方法。


###考え方
２つの要素の比較を繰り返す。


**▼最少値を求める場合**
・１つ目の要素：
初期値は0番目の値。これを現時点での最少値とする。

２つ目の要素と比較して小さい方を現時点での最少値に入れ替える。


・２つ目の要素：
次の要素。１つづつ繰り上げていく。
常に現時点での最少値と比較される。



###最少値を求める

```python:
def min_val(arr):
  min = 0  #初回は0番目を現在の最少値とする（配列番号で指定）
  for i in range(1, len(arr)):
    if arr[min] > arr[i]:  #比較して次の数値の方が小さければ、現在の最少値の配列番号を入れ替え
      min = i
  print(a[min])
```

```python:
a = [2,4,5,3,10,1,8,6,3,2]
min_val(a)

#1
```



<br>
##max関数を使わずに最大値を求める
if文の中の不等号を入れ替えるだけ。

```python:
def max_val(arr):
  max = 0
  for i in range(1, len(arr)):
    if arr[max] < arr[i]:
      max = i
  print(a[max])
```

```python:
a = [2,4,5,3,10,1,8,6,3,2]
max_val(a)

#10
```
Ruby 繰り返し処理

# はじめに
これは学習用のメモになります。
今回は様々な繰り返し文についてまとめていきたいと思います。

# for文
「for」文ではあらかじめ指定したオブジェクトから順に値を取り出しながら繰り返しを行います。

```
for カウンタ変数 in 繰り返す範囲 do   # doは省略可能
    繰り返し処理
end
```

```
例）HTMLで１歳から１０歳までのプルダウンリスト
puts "<select name='age'>"
for age in 1..10
  puts "<option>#{age}歳</option"
end

puts "</select>"
```

# while文
条件式が真である限り、処理を繰り返します。

```
# whileによるループ処理

# カウンタ変数を初期化
while 条件式 do    # doは省略可能
    #繰り返し処理
    #カウンタ変数を更新
end
```

```
例）
i=1.              //カウンタ変数の初期化
while i <=10      //1から10を繰り返す
  puts i    #繰り返し処理
  i=i+1            #カウンタ変数を更新
end
```


# if文(条件分岐)

```
if 条件式
  条件式が成り立ったときの処理
else
  条件式が成立しなかったときの処理
end
```

```
number = 1
if number == 1
  puts "数字は1です"
else
  puts "数字は1ではありません"
end
```

[実行結果]

```
数字は1です
```


## 複数の条件式
```
if 条件式
  条件式が成り立ったときの処理
elsif 条件式2
  条件式2が成立したときの処理
else
  条件式がどれも成立しなかったときの処理
end
```
# each文
each分とは配列の要素を順番に取り出して処理を行うことができる

```
配列.each do |変数名|
  #実行したい処理
end
```

```
names = ["Masato","Okachan","Saitou"]

names.each do |name|
  puts "名前は#{name}です"
end
```

[実行結果]

```
名前はMasatoです
名前はOkachanです
名前はSaitouです
```

# 最後に
間違っている部分があるかもしれないですがその時はご指摘いただけると幸いです。
[iOS14]ヒラギノフォント使用時のUILabelの高さ調整

## 概要
iOS14にて、ヒラギノフォントを指定していたUILabelで、 g や jといった、
下にはみ出す文字の下部が見切れるようになったので、その対応。

↓下部が見切れている。
![スクリーンショット 2020-10-16 15.40.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36475/1045596c-7aa0-ce8e-86ff-4920da19c249.png)


問題の詳しい解説などは以下などを参考にしてください
https://koze.hatenablog.jp/entry/2020/05/11/093000
http://akisute.com/2015/11/ios.html

## 環境
Swift5
Xcode11.3 (Xcode12.0でも動作確認)

## 解決作
*正直この対応で本当に問題がないのか、あまり自信はありません。間違いなどありましたら、ご指摘いただけますと幸いです🙇🏻‍♀️

Extentionで関数使って修正している情報は見つかったのですが、
今回すでに問題が起こりうるヒラギノをつかった箇所がたくさんあり、かつヒラギノの設定はxibでやっていたため、修正もxibやStoryboardでできる方法を探しました。

サイズを調整するカスタムクラスを作成しました。
調整の内容自体は上でも紹介している以下のリンク先の内容と同じです。
http://akisute.com/2015/11/ios.html

```
import UIKit

class HiraginoUILabel: UILabel {
    
    override var intrinsicContentSize: CGSize {
        var size = super.intrinsicContentSize
        // ヒラギノフォントで日本語と英語が混じっている場合のラベルサイズずれ対応
        if let font = self.font,
            font.familyName.hasPrefix("Hiragino") { // 念の為ヒラギノフォントであること確認
            size.width = ceil(size.width);
            size.height = ceil(size.height + abs(font.descender));
        }
        return size;
    }
}
```

これで、xib側で、ヒラギノを指定しているLabelにカスタムクラスを指定すると、高さが自動で調節されます。
念の為カスタムクラス側でフォントを確認しているため、他のフォントに変わってクラス指定を外すことを忘れても、何もしないようにしています。
![スクリーンショット 2020-10-14 13.16.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36475/18135c70-973f-a98d-49a7-2139c54c4e78.png)

↓対応後
![スクリーンショット 2020-10-16 15.40.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36475/6becbb63-c245-bf4f-a6c6-8c6f18cbfb0d.png)


以上です。
jestを使って4つのフェーズでテスト

#テストにおける4つのフェーズについて

テストには、4つのフェーズでテストする方法があり、

```
1.準備(setup)、
2.実行(exercise)、
3.検証(verify)、
4.後片付け(teardown)
という流れになっています。
```

今回は、nodeで実装しています。

テストのときだけdynamoDBにデータを入れるようにし、
そのデータを使ってラムダを呼んだ時のテストをしています。

～意識すること～
➡test()の中でsetup～teardownを行う。そうすると、テストケースごとに、パラメータやテストデータやレスポンス内容などキレイに分けることができる。

```
1.準備(setup)
➡パラメータの用意をしたり、データベースにテスト用のデータを入れたり。
テスト前にあらかじめテスト用のデータを入れておくのもよいですが、
テストのときだけとあるデータを入れてテストをしたくなる場合があるので、
今回はテストのときにデータを入れる感じにしています。

2.実行(exercise)
➡テスト対象の関数を呼ぶ

3.検証(verify)、
➡jestのexpectを使ってレスポンス内容が意図したものになってるかを検証

4.後片付け(teardown)
➡DB接続を切断したりする例があったりしますが、そういうのは内部でやってるので今回は無し
```

## プログラム

```typescript:anime-suko.ts

const putHogeTable = () => {
  return new Promise((resolve) => {
    const items = [
      {
        id: 'hoge-00001',
        name: 'あやねる',
      },
      {
        id: 'hoge-00002',
        name: '小倉',
      },
    ]

    interface ItemsInterface {
      id: string
      name: string
    }

    const putRequest: { PutRequest: { Item: ItemsInterface } }[] = []
    items.forEach((item) => {
      const obj = {
        PutRequest: {
          Item: item,
        },
      }
      putRequest.push(obj)
    })

    const params = {
      RequestItems: {
        requester: putRequest,
      },
    }

    documentClient.batchWrite(params, (err, data) => {
      if (err) {
        console.log('[ERROR] ' + err)
        resolve(null)
      } else {
        resolve(data)
      }
    })
  })
}

//共通setup
const putCommon = () => {
  putHogeTable()
}

/*
 * 正常系1(全てのパラメータが存在する) 
 * 前提条件：パラメータ内にメッセージID(messageID)が存在すること
 * 期待結果：ステータスコードが200で返ってくること
 */
const testCase1 = test('正常系1(全てのパラメータが存在する)', async () => {
  //setup
  putCommon()
  const testSuccessParameterJson2 = {
    id: 'hoge-00001',
    messageID: 'hogeMessage1',
  }
  const testSuccessParameterStr2 = JSON.stringify(testSuccessParameterJson2)

  jest
    .spyOn(callLambdaModule, 'callLambda')
    .mockResolvedValueOnce(Promise.resolve({ statusCode: 200 }))
  const testSuccessExpectResponse = {
    statusCode: 200,
  }

  //Exercise
  const actual = await hogeLambdaFunction()

  //verify
  //ステータスコードが200で返ってくること
  expect(actual).toStrictEqual(testSuccessExpectResponse)
})

```

## まとめ
jestでのテストの方法をググったりすると、普通にレスポンスが意図したものかどうかみたいな記事はいっぱい見つかるが、今回扱った4つのフェーズを
意識したテストというのを会社で学べたのは良かった。
php デフォルトセキュリティ

https://www.acrovision.jp/career/?p=1996

https://s8a.jp/php-security-1#%E3%81%BE%E3%81%A8%E3%82%81
https://hacknote.jp/archives/180/
https://qiita.com/knife0125/items/0e1af52255e9879f9332
http://wordpress.honobono-life.info/svrmng/%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3%E3%82%92%E8%80%83%E6%85%AE%E3%81%97%E3%81%9Fetcphp-ini%E3%81%AE%E8%A8%AD%E5%AE%9A/
https://wepicks.net/phpsecurity-directive/
http://web.showjin.me/php_setting.html
【python】配列の値を入れ替える方法

#【python】配列の入れ替え

要素の番号をイコールでつなぐことで要素を簡単に入れ替えることができる。

例えば、1~5の整数が入った配列の先頭と末尾を入れ替えたい場合、それぞれの値を左右で入れ替えてイコールでつなげばOK。

```python:
a = [1,2,3,4,5]

a[0], a[4] = a[4], a[0]
print(a)

#[5, 2, 1, 4, 5]
```


<br>
##何をしているか？
指定した値に、指定した値を入力できる処理を応用している。

```python:
a = [1,2,3,4,5]

a[0], a[1], a[2] = a[4], a[4], 5
print(a)

#[5, 5, 5, 4, 5]
```


###シンプル版
変数名をつけていなくても使える。

```python:
a,b,c,d =1,2,3,4
a,c = c, a
print(a,b,c,d)

#3 2 1 4
```




##数が合わない場合
左側の値が一つ以外の場合はエラーになる。
左側がひとつの時は、まとまった値が入る。

```python:
a = [1,2,3,4,5]

a[0] = a[4], a[4], a[4]
print(a)

#[(5, 5, 5), 2, 3, 4, 5]
```


```python:
a = [1,2,3,4,5]

a[0], a[1] = a[4], a[4], a[4]
print(a)

#ValueError: too many values to unpack (expected 2)
```
yumとaptの update / upgrade は違う

## 結論
`yum update`と`apt update`の挙動は違います。※`upgrade`も

## 違い
|コマンド|yum (RedHat系：CentOSなど)|apt（Debian系：Ubuntuなど）|
|:----|:----|:----|
|update| インストール済みのパッケージをアップデート|インストール可能なパッケージの「一覧」を更新<br>パッケージ自体は更新されていない|
|upgrade|パッケージのアップデート(yum update)<br>＋不要になったパッケージの削除|パッケージ構成を変えない範囲でアップグレードする<br>不要なパッケージの削除、カーネルの更新はしない<br>「一覧」が古い（apt updateをしていない）と、古いパッケージを元に更新が実行される|
|full-upgrade|なし|パッケージ構成の変更に追随してアップグレード（yum upgradeと同じ？）|

## 経緯
`yum`と`apt`の挙動は同じだと無意識に思っていた。
CentOSやUbuntuでupdateしたときに、挙動が違ったためメモ。
gretelを用いたパンくず機能の実装方法

![スクリーンショット 2020-10-14 12.49.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/749100/f73b3abe-3bfa-36dd-b107-6789af0abc1f.png)
# What: パンくず機能とは
パンくず機能とはウェブページの上部でよく見かけるこの表示のことです！！
![スクリーンショット 2020-10-14 12.49.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/749100/18727140-4858-ad50-6898-2a6f6c0d3b01.png)



# Why: なぜパンくず機能を実装するのか
パンくず機能とはウェブページにおいてユーザーが現在どのページにいるかを視覚的に確認しやすくするための機能です。

# How: どうやって実装するのか

###step 1:　gemfileの導入
ここでは'gem gretel'をgemfileに追加し、bundle installを実行しましょう。

```
gem 'gretel'
```
```
$ bundle install
```

###step 2: 設定ファイルの作成
bundle installが完了したらrails generate gretel:installを実行しましょう。
すると、configディレクトリにbreadcrumbs.rbが生成されます。
これが設定ファイルになります。

```
$ rails generate gretel:install
```

###step 3: 設定ファイルの記述
生成されたbreadcrumbs.rbに記述していきます。

今回はアイテム変数を用いて階層構造になっているカテゴリの親、子、孫要素をそれぞえ取得して表示させたいと思います。
:warning:ここで一点注意なのですが、ビューで引数に@item変数を引き渡すことに加えて、子要素以降のcrumbのparentに変数itemを追記しないとエラーが発生します！
（原因はわからず、、教えていただけると幸いです！）

```ruby

crumb :root do
  link 'FreeMa', root_path
end

crumb :parent_category do |item|
  link item.category.parent.parent.name, root_path
  parent :root
end

crumb :child_category do |item|
  link item.category.parent.name, root_path
  parent :parent_category, item
end

crumb :grandchild_category do |item|
  link item.category.name, root_path
  parent :child_category, item
end

crumb :current_product do |item|
  link item.name
  parent :grandchild_category, item
end
```

###step 4: ビューの記述

```ruby
    - breadcrumb :parent_category, @item
    - breadcrumb :child_category, @item, class: 'content'
    - breadcrumb :grandchild_category, @item, class: 'content'
    - breadcrumb :current_product, @item, class: 'current'
    = breadcrumbs separator: "  &rsaquo;  "
```

###step 5: ビューの調整

cssで見た目を整えれば、、、


###完成！！

かなり説明を省いてしまいましたが
[公式ドキュメント](https://www.rubydoc.info/gems/gretel)に詳しい説明がありますので、是非一読を！
【参考記事】
[パンくずリストの実装](https://qiita.com/tanaka-t/items/970dff5c04412f573b1e)
[【Rails】gretelを使ってパンくずリストを作成](https://qiita.com/Azure0701/items/16de34a0010eb7f05d89)
[一番わかりやすいパンくずの実装（gem 'gretel')](https://qiita.com/params_bird/items/2c77ac1fe6ea8c4fd065)
Raspberry Pi セットアップ ～Etcher使用Ver～

Raspberry Piのセットアップについてのメモ書き
Windowsでのやり方メモ

###準備する物
microSDカード(64GB以上推奨)
SDカードアダプタ
カードリーダー(使用PCにSDカードスロットあればいらない)

###前準備
①[SD Card Formatter](https://www.sdcard.org/jp/downloads/formatter/
)のインストール
![2020-10-14 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607764/a008e68b-84ac-9172-c377-ef4ddce1e44c.png)![2020-10-14 (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607764/0d827a80-5550-1aac-4d04-f2f617037281.png)
Windows用ダウンロードを選択すればOK

②[balenaEtcher](https://www.balena.io/etcher/)のインストール
![2020-10-14 (10).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607764/85ade18d-eab4-d9da-fda1-9784611f7745.png)
Download for Windows(x86|x64)を選択すればOK


③[Raspberry Pi OS](https://www.raspberrypi.org/)のダウンロード
　→ホーム上部の『Downloads』→『Raspberry Pi OS』を選択→使用したいOSの『Download ZIP』を選択してダウンロードする。

![2020-10-14 (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607764/f3403a94-0e90-8a6c-70a4-4240968b7d42.png)　![2020-10-14 (8).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607764/8f575199-7c90-cace-2558-4265622a42a9.png)

Amazon等でパッケージとして購入すればたいていmicroSDカードが付属しているがその場合はNOOBS版との認識で問題ない。

NOOBS版もいいがここはRaspberry Pi OSを選択。

ここでは最新版のBusterがダウンロードされます。

stretchなどの旧Verを使用したい場合はミラーサイト等でダウンロードする。
[ミラーサイト](http://ftp.jaist.ac.jp/pub/raspberrypi/raspbian/images/)
使用したいVer等は自分で確認する。

###中準備
①適当なフォルダを作って、ダウンロードしたRaspberry Pi OSのZIPファイルを解凍する。
![2020-10-14 (12).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607764/ea91b2da-4c5b-950d-a8d0-4d04240be0c6.png)
必要となるのは上記イメージファイル


②osを書き込みたいmicroSDカードをSD Card Formattterを使ってフォーマットする。
　中にデータがある場合の退避は忘れずに

③balenaEtcherを立ち上げてmicroSDカードにイメージファイルを書き込む。

###microSDカードにOSが書き込めたら
Raspberry PiのカードスロットにmicroSDカードを差し込んで電源入れて立ち上げる。
この辺りについてはWEB上に膨大な量のHOW toがあるのでそれを参照すれば問題なし。
ただ、メモとしてやり方は残す予定。

###まとめ
Amazonでのスターターキットを使うと差せば使えるmicroSDカードが付属しているので
意外とこの辺りが抜ける可能性があり。
慣れた人だと当たり前に出来るが、これからの人だと結構手間取る様な気が…

以上。
Python3 で websockets の async/await を隠蔽する

`asyncio` が入る [websockets](https://websockets.readthedocs.io/en/stable/index.html) を使用した関数が上部に波及してどこまでも `async/await` になってしまうのか…と思っていたところ[自作ライブラリでなんとかなった](https://qiita.com/shirasublue/items/f51986f39dd8a3bf8310)のでその部分の忘備録

# 解決策

- デコレータを使いました

# 環境

- Python 3.8.5
- websockets 8.1


# コード

### my_library.py

```Python3
import websockets
import asyncio

class EntitySpec(object):
    def __init__(self, ctx):
        self.ctx = ctx
        self.uri = "ws://{}:{}".format(
            ctx.hostname, ctx.port,
        )

    def __call__(self, func):
        async def stream(func):
            async with websockets.connect(self.uri) as ws:
                while not ws.closed:
                    try:
                        response = await ws.recv()
                        func(response)
                    except websockets.exceptions.ConnectionClosedOK:
                        self.loop.stop()
        self.loop = asyncio.get_event_loop()
        self.loop.create_task(stream(func))
        return stream

    def run(self):
        self.loop.run_forever()

class Context(object):
    def __init__(
        self,
        hostname='localhost',
        port=8765,
    ):
        self.hostname = hostname
        self.port = port        
        self.websocket = EntitySpec(self)
```


### main.py

```Python3
import my_library

api = my_library.Context(
    hostname = 'localhost',
    port = 8765,  # websockets server サンプル標準ポート
)

@api.websocket
def reciever(msg):
    print(msg)

api.websocket.run()
```
AWS-SDK PHPでS3バケット上のファイルをコピーするときにContent-Typeを変更する

S3に既に配置済みのファイルのContent-Typeを変更する際に苦戦したので、自分用のメモ

## 結論

`copyObject`を使用する際に、オプションで`ContentType`, `MetadataDirective`の2つを指定する。

```php
$s3 = new S3Client([
    'version' => 'latest',
    'region'  => 'us-east-1'
]);

$s3->copyObject([
    'Bucket'     => $targetBucket,
    'Key'        => "{$sourceKeyname}-copy",
    'CopySource' => "{$sourceBucket}/{$sourceKeyname}",
    'ContentType' => 'binary/octet-stream', // ※
    'MetadataDirective' => 'REPLACE', // ※
]);
```

`MetadataDirective:REPLACE`を指定しないと、S3に配置されている元ファイルのContent-Typeを引き継ぐみたいなので注意


## 参考URL

- [AWS SDK for PHP 3.x](https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html)
- [AWS CLIでS3オブジェクトのContentTypeを設定する](https://siguniang.wordpress.com/2014/05/14/update-s3-object-content-type-via-awscli/)
初心者がやりがちな変数命名のアンチパターン

## はじめに
ご存知のようにPythonはその書きやすさからプログラミング初心者にも敷居の低い言語として親しまれており、「初めて触れる言語がPython」という方も少なくありません。
しかしそんなPythonにもやってはいけないアンチパターン(禁じ手)があり、初心者が知らずに踏んでしまうと対処に苦しむ事になってしまいます。
そこで、Pythonのアンチパターンのうち、特に初心者が注意すべき**「変数の命名」**の中でも特に致命的な**同名変数定義による代入**についてご紹介させていただこうと思います。

## 悪い例
下のコードは、タプル型変数`tuple`の中身をリスト型に変換して、リスト型変数`list`と結合させるものです。
一見至って普通のデータ操作ですが、これ実は動きません。エラーが出ます。

```py
>>> list = ["Apple", "Orange", "Grape"]
>>> tuple = ("Peach", "Strawberry")
>>> list.append(list(tuple))
```

```py
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'list' object is not callable
```
## 何がまずかった？
原因は1行目にあります。
全体として、Pythonには`list()`という標準組み込み関数があり、これで引数に与えたIterableなオブジェクトをリスト型に変換することができます。

3行目の`append()`の中身`list(tuple)`ではこの関数を呼び出そうとしているのですが、1行目で**`list`の名前でリスト変数を定義してしまったことで、`list`の参照先が上書きされてしまったのです。**
そのため**このコードでは今後`list`が組み込み関数の`list()`ではなく変数の`["Apple", "Orange", "Grape"]`を参照するようになります**。

残念ながらこのコード内では再代入しない限り`list()`関数は二度と使えません。

## 対策
同じように使用を強く非推奨される命名は他にもあり、`str`、`list`、`int`、`dict`、`id`、`bool`等も、一時変数に使いたくなる魅力を放ちながらも、実際に定義してしまうと同名の関数を潰してしまうことになる危険なものとなっています。
たとえ書き捨てコードであっても、これらの命名は決して使ってはいけません。
そこで、個人的なおすすめの命名は、これらを**接尾辞として変数名の一部に入れる**ことです。
上記の例であれば、

```py
list = ["Apple", "Orange", "Grape"]
tuple = ("Peach", "Strawberry")
```
を、

```py
fruits_list = ["Apple", "Orange", "Grape"]
fruits_tuple = ("Peach", "Strawberry")
```
のように**、`[リストの抱える要素の総称]_[データ型]`**の命名が、入っているデータの内容と型を容易に判別できるのでおすすめです。

## 命名はできるだけ一意なものが望ましい
#### 組み込み関数だけでなく、同名のオブジェクトが存在する命名は避けたほうが幸せ
今回上げた例は`list()`という関数の話ですが、**Pythonでは予約語以外のあらゆる変数を自由に定義・代入できてしまう**という特性があり、注意しないと変数の上書きや関数へのアクセスを失ってしまうことになるので、変数は**「他と被らない命名」**をできるだけ心がけるといいと思います。
標準組み込み関数だけでなく、コード内やimportしたパッケージに存在するメソッドとの競合も気をつけてるべきでしょう。
コードサジェスト機能が存在するエディタなら、**新規変数を定義しようとしたとき、サジェストに同一名の候補が列挙されたら使用しない**という手も有効かもしれません(下画像はVisualStudioCodeのサジェスト)。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398976/aa4d81ff-3e07-0ae2-c6a1-8dbf75ac1925.png "listがサジェストに上がったのでこの命名は諦めるが吉")

## まとめ
+ 同一名の関数/変数が存在する変数を新たに定義してしまうと、関数が使えなくなってしまったり、その前に定義されていた変数の値を失うことになる。
+ 変数の命名は`[リストの抱える要素の総称]_[データ型]`が、安全かつ可読性に優れた例としておすすめ
+ キーワードサジェストを参考に変数命名アンチパターンを回避できる。

**変数名に注意を払うようになると、可読性がぐっと上がり、コード全体の処理過程も追いやすくなります。
これによりバグの早期発見の確率も上がり生産性の大きな向上も見込めるでしょう。**

コードを書く際には変数の命名を見直してみてください。

最後まで読んでいただきありがとうございましたm(_ _)m
修正点、加筆すべきことありましたら教えていただけると幸いです。
[terraform] 用意されてないresourceはnull_resourceで対応する

## 簡易的な例

```terraform
resource "null_resource" "hogehoge" {
  triggers = {
    fugafuga = "fugafuga" // ここが変わると直下に記載してあるlocal-execが実行される（whenが指定されてない方）
  }
  provisioner "local-exec" {
    interpreter = ["ruby", "-e"]
    command     = "puts 'hogefuga'"
  }
  provisioner "local-exec" {
    interpreter = ["ruby", "-e"]
    command     = "puts 'fugapiyo'"
    when        = destroy // こっちは削除時に実行される（whenで指定してあるため）
  }
}
```

## 具体例

```terraform
resource "google_bigquery_dataset" "shared_udf" {
  dataset_id = "shared_udf"
  location   = local.japan_tokyo_region
}

locals {
  japan_tokyo_region = "asia-northeast1"
  udfs = {
    example : <<EOF
CREATE OR REPLACE FUNCTION ${google_bigquery_dataset.shared_udf.dataset_id}.example(x INT64)
RETURNS INT64
  LANGUAGE js AS """
  return x*2;
""";
EOF
  }

}

resource "null_resource" "udfs" {
  for_each = local.udfs
  triggers = {
    udf = each.value
    project_id = var.project_id
    location = local.japan_tokyo_region
    udf_dataset_id = google_bigquery_dataset.shared_udf.dataset_id // destroy時のwarningへの暫定対応 望ましくないがとりあえず https://github.com/hashicorp/terraform/issues/23679
  }
  provisioner "local-exec" {
    interpreter = ["bq", "query", "--use_legacy_sql=false", "--project_id=${self.triggers.project_id}", "--location=${self.triggers.location}"]
    command     = each.value
  }
  provisioner "local-exec" {
    interpreter = ["bq", "query", "--use_legacy_sql=false", "--project_id=${self.triggers.project_id}", "--location=${self.triggers.location}"]
    command     = "DROP FUNCTION IF EXISTS ${self.triggers.udf_dataset_id}.${each.key}"
    when        = destroy
  }
}
```

## 参考
* [null_resource](https://www.terraform.io/docs/provisioners/null_resource.html)
* [local-exec](https://www.terraform.io/docs/provisioners/local-exec.html)
* [Destroy-Time Provisioners](https://www.terraform.io/docs/provisioners/index.html#destroy-time-provisioners)
GitHubについて備忘録。。


# clone
cloneコマンドは一言で言えばリポジトリ(ファイルやディレクトリの状態)をコピーするためのコマンド。主にみんなで活用しているリモートリポジトリをクローンして、自分の開発用にローカルリポジトリを作るために使います。

# fork
一般的にフォークは、他のユーザのプロジェクトへの変更を提案するため、あるいは他のユーザのプロジェクトを自分のアイディアの出発点として活用するために使用します。
(他人のリポジトリを自分のアカウントの**リモートリポジトリ**にコピーすること)


# forkによるワークフロー
1. 元となるリポジトリをfork
2. forkしたリポジトリBをローカルにclone
3. cloneしたリポジトリCで開発し、リポジトリBに反映
4. リポジトリAの管理者にPull Requestを送信

# フォークした後のワークフロー
GitHubでフォークした後にフォーク元の差分を取り込む時の手順になります。

ローカル環境で該当プロジェクトのディレクトリに移行して、フォーク元のリポジトリを登録します。

```
$ git remote add upstream git://github.com/ユーザー名/リポジトリ
```
上記はフォーク元のURLになります。

フォーク元からの内容を取得して、自分のmasterにマージします。

```
$ git fetch upstream
$ git merge upstream/master
```
これでフォーク元の差分を取り込むことができます！
【Python】転置行列を内包表記で求める

#転置行列について


```
A = [
    [a1_1, a1_2, ..., a1_W],
    [a2_1, a2_2, ..., a2_W],
       :     :    :     :
    [aH_1, aH_2, ..., aH_W]
]
```
上のような行列Aを、

```
At = [
    [a1_1, a2_1, ..., aH_1],
    [a1_2, a2_2, ..., aH_2],
       :     :    :     :
    [a1_W, a2_W, ..., aH_W]
]
```
上のAtのように変形させた行列のことを指します。

#実装

```python:displace.py
A = [
    [1, 2], 
    [3, 4], 
    [5, 6]
]

H = 3
W = 2

At = [[A[i][j] for i in range(H)] for j in range(W)]

print(*A, sep="\n")
print("")
print(*At, sep="\n")

```

#実行結果
```
 > displace.py
[1, 2]
[3, 4]
[5, 6]

[1, 3, 5]
[2, 4, 6]
```
成功。
機械学習時に使えそうな画像自動収集パッケージ「icrawler」(0.6.3)の紹介


画像を使った深層学習で面倒な画像集めを行うパッケージの紹介。

検索エンジンから画像を収集したり、画像投稿SNSや、webページからの画像をまとめて自動でDLできる

googleの画像検索エンジンの仕様変更に伴ってgoogle用の関数はまだ使えない様子
当記事投稿(2020-10-10)の4日前にもgoogleクローラーの修正が行われていたので、いずれ改善するのではないでしょうか。



#検索エンジンからのダウンロード

bing,baiduからのダウンロード


```python
from icrawler.builtin import BaiduImageCrawler, BingImageCrawler, GoogleImageCrawler


bing_crawler = BingImageCrawler(downloader_threads=4,storage={'root_dir': 'C:\\Users\\Desktop\\0\\your_dir'})
bing_crawler.crawl(keyword='cat', filters=None, offset=0, max_num=10)
```

画像の保存先をstorageに指定する
rooot_dirの後にpathでなく、文字を指定してやれば作業ディレクトリ中に指定した文字のファイルを自動作成してそこに収集される


keyで検索ワードを指定する

```python
baidu_crawler = BaiduImageCrawler(storage={'root_dir': 'your_image_dir'})
baidu_crawler.crawl(keyword='cat', offset=0, max_num=100,min_size=(200,200), max_size=None)
```

max_numを1000に指定したところ800くらいまではDLされる
同じディレクトリを指定した場合の挙動は、ファイルの名前と拡張子が被っていた場合skipする


#webサイトからのダウンロード


webサイト上の画像を片っ端から探しながらダウンロードしてくれる
ダウンロード後の振り分けが必要


```python
from icrawler.builtin import GreedyImageCrawler

greedy_crawler = GreedyImageCrawler(storage={'root_dir': 'di'})
greedy_crawler.crawl(domains='https://ダウンロードしたい画像のあるURL.html', max_num=10,min_size=None, max_size=None)
```



#SNS(Flickr)からのダウンロード



Flickrの検索結果をもとに画像をダウンロードする
メアドと名前程度の簡単なユーザー登録が必要(google mailではconfirmできない？)


sign in したあとAPIkeyをリクエストすることで使える

[APIのリクエスト](https://www.flickr.com/services/apps/create/)

非営利であること、利用目的、などを記入してAPIkeyを発行後コードを動かす


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/318eb987-cd04-7363-a954-d3143900dc50.png)



```python
from datetime import date
from icrawler.builtin import FlickrImageCrawler

flickr_crawler = FlickrImageCrawler('発行したkeyをここに',
                                    storage={'root_dir': 'image_dir'})
flickr_crawler.crawl(max_num=100, tags='cat,dog',
                     min_upload_date=date(2019, 5, 1))
```



#動作確認できていないがgoogleの場合

少し前までは100件しかダウンロードできない、という問題はあれどダウンロード自体はできてたんですけど
現在はダウンロードすら確認できなくなっていました

```python
from icrawler.builtin import BaiduImageCrawler, BingImageCrawler, GoogleImageCrawler

google_crawler = GoogleImageCrawler(
    feeder_threads=1,
    parser_threads=1,
    downloader_threads=4,
    storage={'root_dir': 'er'})

google_crawler.crawl(keyword='cat', offset=0, max_num=10,
                     min_size=(200,200), max_size=None, file_idx_offset=0)
```





#以上

参考サイト
[Welcome to icrawler](https://icrawler.readthedocs.io/en/latest/index.html)
openpyxlのオフラインインストール手順

やったのでメモ。

# 前提条件
- Windows 10 64bit
- Python 3.8.0

# 必要なもの
[pypi.org](https://pypi.org/ )から以下の最新版を事前にダウンロードしておく

| 名前 | 形式 | 備考 |
|---|---|---|
|openpyxl | .whl ||
|jdcal | .whl | openpyxlに必要。|
|et_xmlfile | setup.py | openpyxlに必要。tar.gz形式のみダウンロードできるので解凍しておく|

# インストール
```PowerShell
py -m pip install .\jdcal-1.4.1-py2.py3-none-any.whl   # py -mを先頭に置くことでpipにPATHが通っていない場合でもpip叩けるようになる
python .\dist\et_xmlfile-1.0.1\setup.py install --user # user指定しないとカレントディレクトリにインストールされてしまう
py -m pip install .\openpyxl-3.0.5-py2.py3-none-any.whl
```

# サンプル
sample.xlsxの全Sheet名とSheet数を表示するスクリプト

```Python:get_sheet_names.py
import openpyxl
book = openpyxl.load_workbook("sample.xlsx")
names = book.sheetnames
print(names)
print("---------")
print(len(names))
```
TypeScript で Express を使う

次の記事を参考にしました。
[Node+TypeScript+ExpressでAPIサーバ構築](https://qiita.com/pochopocho13/items/79a4735031ce11a91df7)



<ol>
<li>package.json を作成</li>

```bash
npm init -y
```

<li>typescript のインストール</li>

```bash
npm install -D typescript @types/node
```

<li>tsconfig.json を作成</li>

```bash
./node_modules/.bin/tsc --init
```

<li>express をインストール</li>

```bash
npm install -D ts-node
npm install express
npm install -D @types/express
```

<li>package.json を編集</li>

```text:package.json
（省略）
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "tsc": "tsc",
    "ts-node": "ts-node"
  },
（省略）
```

<li>index.ts を作成</li>

```ts:index.ts
import express from 'express'

const app: express.Express = express()

// CORSの許可
app.use((req, res, next) => {
  res.header("Access-Control-Allow-Origin", "*")
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept")
  next()
})

// body-parserに基づいた着信リクエストの解析
app.use(express.json())
app.use(express.urlencoded({ extended: true }))

// GetとPostのルーティング
const router: express.Router = express.Router()
router.get('/get_test', (req:express.Request, res:express.Response) => {
	const str_out:string = "Hello " + req.query.name + "\n"
  res.send(str_out)
})
router.post('/post_test', (req:express.Request, res:express.Response) => {
    const str_out:string = "Morning " + req.query.name + "\n"
  res.send(str_out)
})
app.use(router)

// 3000番ポートでAPIサーバ起動
app.listen(3000,()=>{ console.log('Example app listening on port 3000!') })
```

<li>サーバーの起動</li>

```bash
npm run ts-node index.ts
```

<li>クライアントで確認</li>

```text
$ curl http://localhost:3000/get_test?name=John
Hello John
$ curl http://localhost:3000/get_test?name=Mary
Hello Mary
```

```text
$ curl -X POST http://localhost:3000/post_test?name=John
Morning John
$ curl -X POST http://localhost:3000/post_test?name=Mary
Morning Mary
```

<li>Httpie で確認</li>

```bash
http :3000/get_test name==John
http :3000/get_test name==Mary
```

```bash
http POST :3000/post_test name==John
http POST :3000/post_test name==Mary
```

</ol>

## 確認したバージョン

```text
$ node --version
v20.2.0
$ npm --version
9.6.6
```
kabuステーション®API - PUSH API用にPythonラッパーをアップデートした

# 概要

[python-kabusapi](https://github.com/shirasublue/python-kabusapi) という [kabuステーションAPI用Pythonラッパーを作成した](https://qiita.com/shirasublue/items/16ff9d1fea54b0ef648e)が、REST APIのみの対応であり、PUSH API によるwebsocket配信には未対応であった。

そのため、「[kabuステーション®APIのWebsocketをPythonで受ける](https://qiita.com/shirasublue/items/222c2bc7dbf284d24878)」のようなコードを書く必要があったが、初心者にとって [asyncio](https://docs.python.org/ja/3.8/library/asyncio.html) 等の概念が煩雑であるため、そのあたりを排除できるよう、ライブラリをアップデートした。


# 環境

- Windows 10
- Python 3.8.5 ( Microsoft Store からインストール )


# 追加パッケージ

- websockets
- requests


# コード

```Python3
import kabusapi

url = "localhost"
port = "18081"  # 検証用, 本番用は18080

# 初期設定　PUSH配信にトークン・パスワードは不要
api = kabusapi.Context(url, port,)

# 受信用関数　情報が受信される度にここが呼ばれる
@api.websocket
def recieve(msg):
    # ここで処理を行う msgはdict形式である。
    print("{} {} {}".format(
        msg['Symbol'],
        msg['SymbolName'],
        msg['CurrentPrice'],
    ))

# 受信開始
api.websocket.run()
```

# 関連記事

- 次回：[kabuステーション®API - PUSH APIから情報を取得・保存し、表示する](https://qiita.com/shirasublue/items/9038b187ef465019d31c)
- 前回：[python-kabusapiの使い方](https://qiita.com/shirasublue/items/bbd8b5860612904deea0)
Excelエラー「修復されたレコード: /xl/drawings/drawing1.xml パーツ内のスケッチ (図形描画)」


# Excelエラー

## 概要
エクセルを開くと、「修復されたレコード: /xl/drawings/drawing1.xml パーツ内のスケッチ (図形描画)」と表示されて、正常に開けない。

## 事象詳細

1. せっかく作ったエクセル方眼紙を開くと以下のメッセージ。
  ![excel11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89437/ca3d3c3a-5a93-b2d3-d9c4-6cad88757a50.png)

1. 恐る恐る「はい」を押してみる。

1. すると、「修復されたレコード: /xl/drawings/drawing1.xml パーツ内のスケッチ (図形描画)」とでる。
  ![excel12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89437/49d34869-b21b-2fd1-5cca-45fb37b7453d.png)

1. せっかく書いたお絵描きが全部消えている。

1. 「いいえ」も試してみるが、改善せず。

1. 落胆..


## 対処

1. LibreOfficeで開く。
1. 名前を付けて保存で「Excel 2007-365(*.xlsx)」を指定。
1. 保存したxlsxを開く
1. 見た目はとりあえず復活してる。が、コネクタがコネクタじゃなかったり、いろいろ細かい点が変わってる。


## 備考
LibreOffice 7.0.2.2で確認
RealSense D415 を Raspberry Pi Zero W で使う

#概要
RealSense D415 を Raspberry Pi Zero W で駆動させることができた。
librealsenseをビルドするときに、FPUをneonからvfpに修正する必要があった。
また、サンプルプログラムにOpenCVを使用したが、librealsenseのビルド前にlibopencv-devをインストールしないとビルドに失敗した。

#ビルド手順
基本的な手順はこちらのRaspberry Pi 4 へのインストール記事を参照した。
https://qiita.com/nv-h/items/3bd206bebf9303dd6624

##OpenCVのインストール
詳細は未調査だが、librealsenseのビルドが途中でフリーズする問題が発生していたが、サンプルプログラム作成に使っていたOpenCVのインストールをビルド前に行ったらなぜか解消した。

```
sudo apt install libopencv-dev
```

##librealsenseのビルド
上記記事のとおりに[librealsense](https://github.com/IntelRealSense/librealsense)をそのままビルドすると、ビルドは成功するものの、``examples/hello-realsense``などを実行すると``Illegal instruction``というエラーを吐いて落ちる。

###FPUの設定変更
RasPi Zeroはneonが無いが、arm系の環境ではFPUにNeonが設定されることが原因のようだった。
そこで、`CMake/unix_config.cmake`の11行目付近の``-mfpu=neon``を``-mfpu=vfp``に変更。

```CMake/unix_config.cmake
set(CMAKE_C_FLAGS   "${CMAKE_C_FLAGS}   -mfpu=vfp -mfloat-abi=hard -ftree-vectorize -latomic")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=vfp -mfloat-abi=hard -ftree-vectorize -latomic")
```

この状態で再度cmakeおよびmakeすると、``examples/hello-realsense``が正常動作した。

#おまけ
せっかくコンパクトな実行環境なので、短いケーブルでRasPiとD415を直結しようと思ってMicro-B(OTG) to Type-CのUSBケーブルを探したら、[Amazon Basicのケーブル](https://www.amazon.co.jp/gp/product/B01LONQ7R6/)がヒットした。Micro-B側がOTGになるかどうか、Micro-B側からType-C側に電源供給されるか不安だったが、無事動いた。
リモートリポジトリのブランチをローカルに取り込む

## リモートリポジトリのブランチをローカルに取り込む

リモートリポジトリのブランチ（origin/[ブランチ名]）を
任意のブランチ名でローカルに作成する

```powershell:terminal
git checkout -b [ブランチ名] origin/[ブランチ名]
```
（２）Vue + Vuetify をVisual Studio Codeで実行・デバッグ

Vue, Vuetifyがインストールされていない場合は、[前の記事（Vue + Vuetifyでローカル開発環境をセットアップ）](https://qiita.com/kztmy/items/b0d8b824b777b7f839bd)を参照しながら、Node.js, Vue, Vue CLI, Vuetifyのインストールをしてください。
この記事中のスクリーンショットはMacOSのものですが、Visual Studio CodeのTerminalを使えば、操作はほぼ同じです。
以下に入る前に、Visual Studio Codeを[ダウンロード](https://azure.microsoft.com/ja-jp/products/visual-studio-code/ "Visual Studio Codeダウンロード")しインストールしておいてください。

#Debug環境の設定

まず、Visual Studio Codeで、Vueのソースコードに対して、ブレークポイントを設定し、ステップ実行しながらデバッグができることを確認します。

- Visual Studio Codeを起動し、Fileメニューから"New Window"を選択してWorkspaceを作る。
- Welcomeと表示されたページの、左側にある、Startの"Open Folder..."を選択するか、Fileメニューから"Add folder to workspace..."を選択し、[前の記事](https://qiita.com/kztmy/items/b0d8b824b777b7f839bd)で作成した、"test002"のフォルダーをWorkspaceに追加する。

![vscode_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69430/0815dc8c-2f8b-9000-9b26-9143975b2bf3.png)

- Debugの設定をするために、左側のデバッグボタンを押し、"create a launch.json file"を選択。Select Environment...で"Chrome"を選択。
- ファイルの作成場所を、workspaceに作成するかlaunch.jsonファイルを別途作成するかを聞かれる場合もあります。どちらでも構いませんが、ここでは、launch.jsonファイルを作成しました。これによって、test002/.vscode/launch.jsonファイルが作成されます。

![vscode_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69430/f63e9ae0-4829-6eb6-d748-30b7108f6461.png)

#Terminalでローカルのサーバを起動し、Debug開始

- Terminalメニューから"New Terminal..."を選択すると、下にshellあるいは、コマンドプロンプトが表示されます。作業ディレクトリは、test002になっているはずなので、ここで、

```> npm run serve```

と入力すると、開発用のローカルサーバが起動します。

![vscode_9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69430/84f856cc-d27b-9245-09fb-c6bd6da3e140.png)


- ローカルサーバが起動したことを確認して、左上の三角のボタンを押して、デバッグの開始をします。

![vscode_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69430/0a498698-bb95-a12e-a36c-5e21b3fa4d91.png)

- Chromeが起動して、自動的に localhost:8080に接続された状態になります。
- 停止するには、表示されているフロートメニューの停止を押します。

<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69430/5aacc33e-c756-3e1d-b6b5-a9992cfff9b9.png width="50%"/>

#ステップ実行

デバッグには、ソースコード上でブレークポイントを設定し、ステップ実行が有効ですが、この環境でできるか確認してみましょう。

- main.jsファイルを選択して、ブレークポイントを設定します。ブレークポイントは、ソースコードの頭をクリックすると設定できます。ここでは、main.js内の、"Vue.config.productionTip = false"という行の頭をクリックします。赤い印がつけば、ブレークポイントが設定できています。

![vscode_6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69430/12bd8cc9-adec-9be1-7741-5e97f08d8c0e.png)


- 再度、左側のデバッグボタンを押し、左上の三角のボタンから、デバッガを起動すると、以下のように、ブレークポイントで停止した状態になることが確認できます。
- さっきのフローティングメニューから、ステップ実行、ステップイン、実行を続ける、などを選択してデバッグを行うことができます。

![vscode_7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69430/e88ba460-72d4-8e31-21ed-802a18bac9d0.png)

- ローカルのサーバを停止するには、Visual Studio Codeを終了するか、Terminalで、Cntl+C を入力すれば、サーバは停止します。

# workspaceの作成
- 最後に、Visual Studio Codeのworkspaceを保存します。Fileメニューから、"Save Workspace As..."を選択します。
- test002ディレクトリに、"test002.code-workspace"として、保存します。
- WorkspaceファイルをGitの管理から除くために、".gitignore"ファイルを選択して、最後の行に、*.code-workspaceを追加しておきます。

<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69430/a020bbce-6db7-b01c-27c9-ce8fd879cf74.png width=70%/>

#まとめ
この記事では、Visual Studio Codeから、ローカルでサーバを起動し、Vueのアプリケーションの実行、ブレークポイントの設定ができることを確認しました。
Androidアプリの申請。最初のリリース。「製品版としての公開を開始」ボタン押下でどうなる？


## 即公開 or 審査？？
製品版をリリースする時に、必要な情報や、AppBundle or APKを用意すると最終的に以下の画面となります。「製品版としての公開を開始」ボタンを押すと、審査が入るのか、それとも即公開となるのかが気になりました。
実に、２年ぶりくらいのアプリ公開で、審査がApple並になってるとの事、プロモーションやマーケティングなどと並行する場合はタイミングが大事となりますので、実際にどうだったか簡単に載せます。

※リリースのレビュー →　製品版としての公開のようになります

#### 1.リリースのレビューがある画面
|![ad_release01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297965/546ebc17-e45f-8e8e-4a8b-2c753669eaab.png)|
|:--|
リリースのレビューボタンを押下します
#### 2.公開直前の画面となります。
製品版としての公開を開始ボタンがあります

|![ad_release02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297965/5e7d7f11-6319-619d-aa19-99801e9b1310.png)|
|:--|

製品版としての公開を開始ボタンを押下します
#### 3.製品版としての公開を開始ボタンを押下すると…

審査中になります。即公開ではありませんので、気をつけましょう！

|![ad_qi_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297965/757b4221-fd70-5bab-b85f-63ad442cc724.png)|
|:--|

審査が24〜48時間くらいかかりまして、いつの間にか公開されていました。
iOSやiPadアプリと異なり、審査後に手動公開の様な方法は取れないようです。

#### 追記
アプリをアップデートする時は、公開タイミングなど指定できます。
Rubyでゼロ埋め(0埋め)しようとしたらrubocopさんに怒られる

## 問題
rubocopさんが怒ってきた...怖い...

```
C: Style/FormatStringToken: Prefer annotated tokens (like %<foo>s) over unannotated tokens (like %s).
        format('number: %03d', 1)
                        ^^^^
```

## 解決方法
formatでは、hashを用いて、引数指定を設定できるので、そちらで回避します。

```ruby
format("number: %03<number>d", number: 1)
#=> "number: 001"
```

## 参考
- [RuboCop::Cop::Style::FormatStringToken](https://www.rubydoc.info/github/bbatsov/RuboCop/RuboCop/Cop/Style/FormatStringToken)
- [module function Kernel.#format](https://docs.ruby-lang.org/ja/latest/method/Kernel/m/format.html)
- [Rubyで数値の0埋め](https://blog.toshimaru.net/ruby-0-padding/)
Gitで.onionなリモートリポジトリを扱う

gitで.onionドメインのような通常の方法で解決できないドメインを使うときは、sock5プロキシを使います。
sock5プロキシで利用するポートは9050ですが、9051の場合もあります。

```bash
git -c http.proxy=socks5h://127.0.0.1:9050 clone http://hoge.onion/foo.git
```
バッチを汎用利用して運用を効率化する

#概要
Windowsのタスクスケジューラーでタスク設定する際、パラメータをオプション設定してバッチを汎用的に利用する方法を紹介します。

#こんな時にオススメ
* アウトプットを分けたい
* ログもそれぞれで出力したい
* でも処理がほとんど同じ（バッチを分ける程でもない）

⇒できれば１コのバッチで運用していきたい！

#実装サンプル
###(前提)
```ruby:実行されるコマンドのイメージ
Cscript Sample.wsf /param:1
```
###(パラメータ取得)

```ruby:Sample.wsf
Public Function SetParameter(ByRef parameter)
	If WScript.Arguments.Named.Exists("param") Then
		parameter = WScript.Arguments.Named("param")
	Else
		WScript.Echo "パラメータなし"
		WScript.Quit
	End If
End Function
```
###(個別ログ出力)
* バッチ名にパラメータを付けることで個別に作成できます

```ruby:Sample.wsf
Public Function SetLogFileName(ByVal parameter)
	SetLogFileName = "log_" & WScript.ScriptName & "_" & parameter & ".txt"
End Function
```
# オプション設定方法
* **「タスクの設定」⇒「操作タブ」⇒「新規」**を選択してで各設定値を入力します（その他の設定は適宜行ってください）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440367/2ef833f9-e011-9b25-9928-e4341cfe64a6.png)

| 入力欄 | 設定サンプル| 備考 |
|:-------|:------|:------|
|プログラム/スクリプト|Cscript|   |
|引数の追加(オプション)|Sample.wsf /param:{値}|・「param」の部分（パラメータ名）は任意です   |
|開始(オプション)|C:\Test\|・バッチファイルの配置ディレクトリを指定します   |

#最後に
同じような事をやろうとしている方の参考になれば幸いです。
Word VBAのColorIndexを可視化してみた

翻訳用のWordマクロをつくっていると、変更した箇所を際立たせるため、ColorIndexをよく使います。

ところが、[マイクロソフト公式のドキュメント](https://docs.microsoft.com/en-us/office/vba/api/word.wdcolorindex)はなんと白黒！
どの名前がどんな色なのか、思い出すのも面倒なので、思い切って可視化しました。

## ColorIndex 色付き早見表

![colorIndex.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758865/36c8842d-fe59-f281-5c1a-1b5d5660370f.png)


左からColorIndex（列挙体）の名前、値（Long）、説明となっています。
説明の部分にそれぞれ対応する色を付けました。

## ColorIndex 色付けマクロ

この表があれば特に不要な気もしますが、コードも記載しておきます。
なお、VBAでは列挙体のキーを順番に取り出すことができなかったので、
表自体は上記のドキュメントからコピーして使っています。

```vb
Public Sub apply_colorIndex()

    Dim cTable  As Table
    Dim i As Integer
    
    Dim cIndex As String
    Dim index As Integer
    
    Set cTable = ThisDocument.Tables(1)
      
    For i = 2 To cTable.Rows.Count
    
        cIndex = cTable.Rows(i).Cells(2).Range.Text
        ' Wordの表組みでは、セルの最後に中黒のような記号（Chr(7)）が入っているので
        ' これを削除したうえでInt型に変換する
        index = CInt(Replace(cIndex, Chr(7), ""))
        ' -1の wdByAuthorは設定していないとエラーになったのでスキップしておく
        If index > -1 Then
            cTable.Rows(i).Cells(3).Range.Font.colorIndex = index
            cTable.Rows(i).Cells(4).Range.HighlightColorIndex = index
        End If
    
    Next i
    
End Sub
```

フォントの色はRange.Fontのメンバーなのに、
蛍光ペンの色はRangeのメンバーだというのが少し納得いきませんが……

これでマクロで色を扱うのが少し楽になりそうです！
【SQL Server】DATETIME型の落とし穴

# 概要
SQL ServerのDATETIME型ではミリ秒が丸め込みされてしまうのでその事象とDATETIME型より細かい単位で日時を判定できる型が存在するので紹介します！

# きっかけ
日付型の値を見ているとなぜか定義した値と違う値になっていることがあって躓いたのがきっかけでした。

```sql
declare @datetime_0 datetime = '2020-01-01 23:59:59.990'
select @datetime_0

-- 実行結果は 2020-01-01 23:59:59.990 になっている

declare @datetime_1 datetime = '2020-01-01 23:59:59.991'
select @datetime_1

-- 実行結果は 2020-01-01 23:59:59.990 になっている

declare @datetime_2 datetime = '2020-01-01 23:59:59.992'
select @datetime_2

-- 実行結果は 2020-01-01 23:59:59.993 になっている

declare @datetime_3 datetime = '2020-01-01 23:59:59.993'
select @datetime_3

-- 実行結果は 2020-01-01 23:59:59.993 になっている

declare @datetime_4 datetime = '2020-01-01 23:59:59.994'
select @datetime_4

-- 実行結果は 2020-01-01 23:59:59.993 になっている

declare @datetime_5 datetime = '2020-01-01 23:59:59.995'
select @datetime_5

-- 実行結果は 2020-01-01 23:59:59.997 になっている

declare @datetime_6 datetime = '2020-01-01 23:59:59.996'
select @datetime_6

-- 実行結果は 2020-01-01 23:59:59.997 になっている

declare @datetime_7 datetime = '2020-01-01 23:59:59.997'
select @datetime_7

-- 実行結果は 2020-01-01 23:59:59.997 になっている

declare @datetime_8 datetime = '2020-01-01 23:59:59.998'
select @datetime_8

-- 実行結果は 2020-01-01 23:59:59.997 になっている

declare @datetime_9 datetime = '2020-01-01 23:59:59.999'
select @datetime_9

-- 実行結果は 2020-01-02 00:00:00.000 になっている
```

上記のように、あれ？？？定義したミリ秒と違う値で取得されてる？？？という疑問が生まれました。
後々調べて自分の知識不足だったのですが、今まで気づかなかったので記事にしてみます:sweat_smile:


# なぜ定義したミリ秒とは異なる値になっている？？？
[Microsoftの公式のDATETIME型のリファレンス](https://docs.microsoft.com/ja-jp/sql/t-sql/data-types/datetime-transact-sql?view=sql-server-ver15)によると、


> 時間の範囲 : 00:00:00 から 23:59:59.997
精度 : 値は、.000、.003、または .007 秒単位に丸められます。

ということらしい！なるほど！
↑の実行結果からもわかるように以下のように丸め込みが行われているみたいです！

> .xx0 ～ .xx1 : .xx0 に丸め込み
> .xx2 ～ .xx4 : .xx3 に丸め込み
> .xx5 ～ .xx8 : .xx7 に丸め込み
> .xx9 : .xx0 に繰り上げ


# もっと精度が細かい日付型
なにやら[DATETIME2](https://docs.microsoft.com/ja-jp/sql/t-sql/data-types/datetime2-transact-sql?view=sql-server-ver15)という、もっと精度が細かくて丸め込みも勝手にされない日付型があるらしい！！！


> 時間の範囲 : 00:00:00 から 23:59:59.9999999
精度 : 100 ナノ秒


これを使えば丸め込みされず、もっと正確な判断ができる！
というわけでDATETIME2型で定義した日時を確認してみてください！

```sql
declare @datetime2_0 datetime2 = '2020-01-01 23:59:59.990'
select @datetime2_0

declare @datetime2_1 datetime2 = '2020-01-01 23:59:59.991'
select @datetime2_1

declare @datetime2_2 datetime2 = '2020-01-01 23:59:59.992'
select @datetime2_2

declare @datetime2_3 datetime2 = '2020-01-01 23:59:59.993'
select @datetime2_3

declare @datetime2_4 datetime2 = '2020-01-01 23:59:59.994'
select @datetime2_4

declare @datetime2_5 datetime2 = '2020-01-01 23:59:59.995'
select @datetime2_5

declare @datetime2_6 datetime2 = '2020-01-01 23:59:59.996'
select @datetime2_6

declare @datetime2_7 datetime2 = '2020-01-01 23:59:59.997'
select @datetime2_7

declare @datetime2_8 datetime2 = '2020-01-01 23:59:59.998'
select @datetime2_8

declare @datetime2_9 datetime2 = '2020-01-01 23:59:59.999'
select @datetime2_9
```


このようにミリ秒・ナノ秒まで考慮するようなシステムを作るときはDATETIME2型を検討してみてはいかがでしょうか！
Ubuntuをホスト、Macをクライアントとする開発環境のすゝめ

ずっとMacを使っていましたが、最近Ubuntuのマシンを自作しました。
自作PCの方が圧倒的にスペックは上なのですが、やっぱりデスクトップ利用としては、UbuntuよりMacOSの方がしっくりくるので、
Ubuntuマシンをホスト、Macをクライアントとした開発環境を構築したいと思います。

## 概要
具体的には、
まず、UbuntuマシンにSSHできるように設定し、Ubuntuマシン上にソースコードを置いて、dockerでWebアプリケーションを立ち上げます。
次に、Ubuntuマシン上のソースコードをMacからSSH経由でコーディングし、MacのブラウザでWebアプリケーションにアクセスして、開発します。

## ホストのIPアドレスを確認する

この後使うので、イーサネットやWifiのIPを確認しておく
wlやenから始まるデバイスのIP(192.168・・・)を確認

```bash:Ubuntu-ホストマシン
$ ifconfig
      ⋮
wlp5s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.11.5  netmask 255.255.255.0  broadcast 192.168.11.255
      ⋮
enp6s0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 192.168.0.2  netmask 255.255.255.0  broadcast 192.168.0.255
        ether 24:4b:fe:5e:0a:0e  txqueuelen 1000  (イーサネット) 
      ⋮
```

## ホストにSSHできるようにする

ホストマシンにopenssh-serverをインストールして、起動します。

```bash:Ubuntu-ホストマシン
$ sudo apt install -y openssh-server # opensshインストール
$ sudo systemctl enable ssh 
$ sudo systemctl restart ssh # openssh-server 起動
```

念のため、公開鍵認証を設定しておきます。

```bash:Mac-クライアントマシン
$ ssh-keygen -t rsa -b 4096 -f <鍵の名前> # 秘密鍵の生成
$ ssh-copy-id -i ~/.ssh/<鍵の名前> [ログインユーザー名]@[ホストのIPアドレス] # ホストへの機密鍵の登録 (上で確認したホストIPを使用)
$ ssh [ホストユーザー]@[ホストのIPアドレス] -i ~/.ssh/<鍵の名前>.pub # sshテスト
```

## SSHの設定ファイルをいじる

`~/.ssh/config` ファイルにSSHするホストの情報を載せておきます。これがないとVSCodeからSSHできません。

```~/.ssh/config
Host my-ubuntu
  Hostname <ホストのIPアドレス>
  User <ログインユーザー名>
  Port 22
  IdentityFile <秘密鍵のパス>
```

それから、これがあるとこんな感じで簡単にSSHコマンドが叩けて便利です

```bash
$ ssh my-ubuntu
```

## VSCodeでSSH接続する


Microsoft製のプラグインがあるので、これを使います。Installしてください。
<img width="420" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263783/6064a86e-4796-b5ef-753b-95529e684a4f.png">

インストールすると左にこのマークが出てくるので、押すと、
![スクリーンショット 2020-10-14 11.29.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263783/39d411d7-5b66-b581-8025-aa3fb6351d0a.png)

SSH先が出てくるので、パスワードを入力して、SSHします！これでSSH経由でソースコードを編集できますね。
![スクリーンショット 2020-10-14 11.31.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263783/eba6d0b2-daa0-31b1-d4c6-26a0da834d49.png)

完全に[こちら](https://blog.serverworks.co.jp/tech/2020/02/20/vscode-remote-ssh/)を参考にしたので、詳細はこちらを見るといいかもです。

## Webアプリにアクセス

今回は、簡単にPHPでビルトインサーバーを立てます。
ホストのIPをそのまま使うために、必ずループバックアドレス(localhost,127.0.0.1)を使ってください。

```bash
$ php -S localhost:8080 index.php
```

あとは、ホストのIPアドレスにブラウザでアクセスします。ポートはビルトインサーバーでしたものにしてください



## 終わり
これやっている人たくさんいると思いますが、やって見たので共有です。皆さんもやって見てください

これからの時代、もしからしたら、EC2上などクラウドのマシンで開発することになってくるのかなと思ってしまいました。時代遅れですね。。。


## 参考リンク
こちら参考にしてやらせていただきました。ありがとうございます。
[openssh-serverのインストール方法について](https://www.hiroom2.com/2018/06/28/ubuntu-1804-openssh-server-ja/)
[SSH公開鍵認証で接続するまで](https://qiita.com/kazokmr/items/754169cfa996b24fcbf5)
[公開鍵認証 設定～接続まで](https://coogi-memo.hatenablog.com/entry/2019/07/22/163121)
[ifconfigの出力結果に書いてあること](https://qiita.com/pe-ta/items/aff8db72530c6baa11b2)
[VSCode の Remote - SSH 機能を使って EC2 上で開発する](https://blog.serverworks.co.jp/tech/2020/02/20/vscode-remote-ssh/)
（自分用・試作）コミットメッセージ作成ツール

コミットメッセージが楽に作成できれば良いなと思い、ツールを作成しました。

https://jsfiddle.net/ghost7492/1cw70k2d/1/

まだ未完成ですが、Qiitaに上げるまでを目標としていたため、取り急ぎ投稿します。
後日、修正していきます。

下記を参考にさせて頂きました。
https://www.tam-tam.co.jp/tipsnote/program/post16686.html

下の作成ボタンを押すとコミットメッセージが出力されます。

■todo
デザイン修正
まだ使っていないので、使いづらい部分の修正
数字のみのパスワードジェネレータコマンドを自作する

## この記事の目標．
pwgen は数字のみのパスワードを生成できません．
ここではC言語を使って，数字のみのパスワードを生成するためのプログラムを作成します．
最終的には，パスワード文字数と生成したいパスワードの数を引数とし，以下のようにパスワードを生成します．

```
$ ./a.out -n 12 2
957376037097
356526608774
```

## 実践
以下のコードを作成しました．

```main.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
int main(int argc, char* argv[]){
 srand((unsigned int)time(NULL));

 int i,ith,nth=atoi(argv[2]);
 if(!strcmp(argv[1],"-n")){
  for(i=0;i<atoi(argv[3]);i++){
   for(ith=0;ith<nth;ith++)printf("%d",rand()%10);
   printf("\n");
  }
 }
 return 0;
}
```
コンパイルして実行すると，上記の出力が得られます．
## 追伸
今回 "-n" を第一引数にしたのは，文字を含めたパスワード発生器に拡張したいためです．
いずれは pwgen を卒業したいものです．
プログラムが実行される仕組みとデータ構造 基本情報技術者 用語解説

# はじめに
Hello World！
今回は基本技術者試験の用語を解説していきます！

[【YouTube動画】プログラムが実行される仕組みとデータ構造](https://youtu.be/ggA78kyd9Sg)
[![プログラムが実行される仕組みとデータ構造](https://img.youtube.com/vi/ggA78kyd9Sg/0.jpg)](https://www.youtube.com/watch?v=ggA78kyd9Sg)

# プログラミング言語
プログラミング言語には大きく分けて2種類あります。
1つは、プログラムを1度まとめてから実行するコンパイラ方式で、C言語、Javaなどがあります。
もう1つは、プログラムを逐次実行していくインタプリタ方式で、Basic、Pythonなどがあります。

# コンパイルから実行までの流れ
コンパイラ方式では、コンパイル、リンカ、ローダという段階を踏みます。

コンパイルでは以下の処理をします。

```
字句解析 -> 構文解析 -> 意味解析 -> 最適化 -> コード生成
```

字句解析で、文字列を単語ごとに区切ります。
構文解析で、文や構造が言語仕様に合っているかチェックします。
意味解析で、変数や型、文が言語の記述仕様に合っているかチェックします。
上記をパスしたら、最適化、コード生成により目的のプログラムが作られます。

プログラムを実行するときは、さらにコンパイルしたものをリンカでまとめ、ローダでプログラムを読み込み実行します。

# 構造化プログラミング
構造化プログラミングとは順次、選択、繰り返しの３つの制御構造によって、処理の流れをまとめ、階層化しプログラミングする手法のことです。

動画内で詳しく説明しているので、ぜひ確認してください。



# データ構造
データを保存する仕組みには、例えば以下のものがあります。
配列はデータを番号付けて保存するデータ構造です。
リストは隣のデータを記憶して保存するデータ構造です。
木構造はデータを条件づけて枝分かれして保存するデータ構造です。

- 配列
- リスト
- 木構造

データの扱い方は次の2つがあります。
キューは先に入れたデータを先に取り出すデータの扱い方をします。
スタックは後に入れたデータを先に取り出すデータの扱い方をします。

- キュー
- スタック

# まとめ
今回は基本情報技術者試験の中でも、コンパイルの仕組みやデータ構造など基礎的な部分を解説しました。
他に解説して欲しい部分があれば、コメントいただければ解説します！

また、[twitter](https://twitter.com/yassun_youtuber)や[youtube](https://www.youtube.com/channel/UCajrdoGzHzDogrNrLYYmGsg/featured?view_as=public)でのコメントもお待ちしています！