OmniAICreator/Qiita-1.07M huggingface dataset:
Data Visualization with pandas

# Bar plot
Bar plots are useful to visualize relationship between a categorical and numerical variables.

```python
# Import matplotlib.pyplot with alias plt
import matplotlib.pyplot as plt

# Look at the first few rows of data
print(avocados.head())

# Get the total number of avocados sold of each size
nb_sold_by_size = avocados.groupby('size')['nb_sold'].sum()

# Create a bar plot of the number of avocados sold by size
nb_sold_by_size.plot(kind="bar")

# Show the plot
plt.show()
```

# Line plots
Line plots are great to visualize change in numerical variable such as sales over time

```python
# Import matplotlib.pyplot with alias plt
import matplotlib.pyplot as plt

# Get the total number of avocados sold on each date
nb_sold_by_date = avocados.groupby('date')['nb_sold'].sum()

# Create a line plot of the number of avocados sold by date
nb_sold_by_date.plot(kind="line")

# Show the plot
plt.show()
```

# Scatter plots

Scatter plots help to visualize relationship between two numerical variables.

```python
# Scatter plot of nb_sold vs avg_price with title
avocados.plot(kind="scatter",x="nb_sold",y="avg_price",title="Number of avocados sold vs. average price")

# Show the plot
plt.show()
```
# Layering histograms on top of each other

```python
# Modify bins to 20
avocados[avocados["type"] == "conventional"]["avg_price"].hist(bins=20,alpha=0.5)

# Modify bins to 20
avocados[avocados["type"] == "organic"]["avg_price"].hist(bins=20,alpha=0.5)

# Add a legend
plt.legend(["conventional", "organic"])

# Show the plot
plt.show()
```

# Heatmap with seaborn
Let's say you have 2 dimensional numpy array V_result and you want to plot it as a heat map

```python
import seaborn as sns
import matplotlib.pyplot as plt

states_row_length = 20
states_col_length = 20
V_result = np.zeros((states_row_length, states_col_length))
for row in range(states_row_length):
    for col in range(states_col_length):
        V_result[row, col] = state_values[State(row + 1, col + 1)]
sns.heatmap(V_result, annot=True, linewidths=2, vmin=0, vmax=20, cmap=sns.color_palette("Reds", 24))
plt.title("Optimal state values")
plt.show()
```
【Mac】Macでコピー＆ペーストを行う

<< [【Mac】MacOSの基本操作を覚える](https://qiita.com/hiroyuki-eguchi-0731/items/99a0d771fda18adac9f0)

# Macでコピー＆ペーストを行う

再び初歩過ぎることなのにわかっていないことに気づく。

WindowsはCtrl＋C、Ctrl+X、Ctrl＋Vで実施するコピー＆ペーストのコマンドわからない。。。
わかってしまえば簡単なんですが、忘れてしまいそうなのでメモしておきます。

| 内容 | 方法 |
| ----- | ----- |
| コピー | command + c |
| カット | command + x |
| ペースト | command + v |

Ctrlボタンがcommandボタンに変わっただけだった。

---

2020-12-31 初稿
【Mac】Macの日本語入力ができなくなった

<< [【Mac】MacOSの基本操作を覚える](https://qiita.com/hiroyuki-eguchi-0731/items/99a0d771fda18adac9f0)

# Macの日本語入力ができなくなった

久しぶりにMacBookを起動して作業しようとしたら日本語入力ができなくなってた。
OSバージョンアップしたからかな？

## 日本語設定できるようにする

日本語設定できるようにしないと何もできないのでなんとかせねば。

### キーボード入力設定を確認する

左上のリンゴマークからシステム環境設定をみるとキーボードの設定があるので開いてみる。

![スクリーンショット 2020-12-31 16.40.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406574/84bf735a-06a6-d2b3-5428-54e45e100568.png)

### 日本語の設定がない

あれ？英語設定しかないね・・・。

![スクリーンショット 2020-12-31 16.26.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406574/e86136c8-156b-4a5d-843c-b0d55fda437b.png)

### 日本語設定を追加する

どうやるのかな？とりあえず左側にある＋ボタンを押してみる。

![スクリーンショット 2020-12-31 16.27.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406574/15142aab-10c3-e4b6-0ab3-3c07ccfafc2d.png)

日本語設定が出てきたのでローマ字入力を選択して「追加」ボタンを押す。

![スクリーンショット 2020-12-31 16.28.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406574/951d5b56-2986-865e-5870-e17efda483d6.png)

できた。よかったよかった・・・。

---

2020-12-31 初稿
Postman で Salesforce の API にアクセスする

## はじめに

Salesforce の API にアクセスするためのツールは以前は Workbench や cURL などが広く使われていた印象ですが、今年公式記事で紹介された Postman が非常に便利なので、いまさらながら本記事にて簡単な使い方を紹介します。

[Explore the Salesforce APIs with a Postman Collection](https://developer.salesforce.com/blogs/2020/03/explore-the-salesforce-apis-with-a-postman-collection.html)

## 準備
Postman を下記URLからダウンロードして、インストールします。
[Postman](https://www.postman.com/)

下記URLからjson形式のファイルをダウンロードします。
[Salesforce APIs for Postman](https://github.com/forcedotcom/postman-salesforce-apis)

Postman を起動して、↑でダウンロードしたjsonファイルをインポートします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669225/37e5f245-8797-68c8-e08a-bb86d467758b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669225/378739f8-4eea-2f40-6201-17ac04ecc9a7.png)

Collections タブに Salesforce APIs が追加されたことが確認できるはずです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669225/b062ce66-8fbc-adb6-fd84-d81dc24e8d21.png)

これで準備は整いました。
それでは Postman を使ってSalesforce組織にアクセスしてみましょう。

## Postmanを使って Salesforce の各種 API にアクセスする

### 1.環境の作成

テンプレート環境(Environment)を複製して、新たに作成された環境に変数(組織のログイン情報など)を設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669225/a967e2e8-1f24-30cd-e836-19e25909a293.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669225/a463bc68-63c8-965f-3ff5-3ec479167a3c.png)

今回は個人のデベロッパー環境にSOAPでログインするので、  `url`、`username`、`password`、`secretToken` を設定しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669225/47807fc2-eedd-90fd-c22b-f7d5ecfd9429.png)


### 2.ログイン

APIコレクションから SOAP Login を選んで「Send」を押すと、組織へのログインが完了します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669225/ee114268-9570-41e9-fee9-f25cfb6f3c6d.png)

環境を開くと、`_accessToken` という変数にセッションIDが自動的に記録されています。これは他のAPI操作時に利用されるので、期限が切れるまで再度のログインは不要です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669225/85f3827c-d245-9649-d957-ca45e577b734.png)


### 3.【使用例】取引先の作成

一例として「取引先の作成」を試してみます。

- Collection のRESTフォルダにある sObject Create を複製
- リソースのオブジェクト名を `Account` に書き換え
- リクエストボディを適当に設定して「Send」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669225/6c25e60f-1dc6-b0ed-63e4-9ce4e49b8080.png)

組織を確認したところ、無事取引先ができています。
他のAPI操作についてもあらかじめテンプレートが用意されているので、多少調べ物をすれば誰でもすぐに使えるようになると思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669225/0031157c-9789-b4a4-f8bd-8542af38975f.png)

## まとめ

Postman は Workbenchとは比較にならないほど便利なツールです。
Salesforceへのアクセス以外でも、APIクライアントとしてひたすら優秀なので、未導入であればぜひ導入をおすすめいたします。
第八回講義メモ

\![Mac OS X-10.15.7](<https://img.shields.io/badge/MacOSX-10.15.7-brightgreen>) \![ruby-2.6.3p62](<https://img.shields.io/badge/ruby-2.6.3p62-brightgreen>) 


# Rake

rakeはmakeのantのruby版.以下に典型的な礼を示す.

```ruby
task :default do
  system 'rake -T'
  exit
end

desc 'hello NAME'
task :hello do
  name = ARGV[1]
  puts "Hello #{name}!"
  exit
end
```

これをRakefileに書き込むことで, 

    > rake

とすることで, taskを表示させることができる.


# System call

Rakefileに最も記述する多い関数はsystemらしい.たとえば, gitのコマンドをいちいち覚えるのがめんどくさいものをメモしておきます.

```ruby
desc 'git push'
task :push2 do
  ["git add -A",
   "git commit -m \'hoge\'",
   "git pull origin main",
   "git push origin main"].each do |comm|
    p comm  #puts comm.green after require 'colorize' 
    system comm
  end
  exit
end
```


# Command line

systemで使える外部のコマンドは遅いので, 別の組み込み関数を使用するらしい.rubyにも用意されているらしく, 以下例.

```ruby
desc 'make list'
task :mk_list do
  # system 'ls -1 ../members/*/README.org'
  Dir.glob('../members/*/README.org')[0..4].each do |file|
    p file
    system "grep qiita_id #{file}"
  end
  exit
end
```


# まとめ

これで, gitにあげる作業をgit pushだけで行えるようになった.これは作業効率化以外にも, 一連の流れを忘れてもRakefileさえ覚えておけば簡単に実行できるようになるので超便利.


# 参考サイト

<https://qiita.com/daddygongon/items/1c2d6d2895333ccf5e62>



------
 - **source** ~/my_ruby/grad_members_20f/members/drop-sd/lectures/no8.org
【初学者向け】Markdown記法の基礎　

# はじめに
昨日からMarkdownについて学習を始めた。いざ書いてみると驚くほど簡単かつ綺麗にドキュメントを書くことができました。
そこで自分用のメモかつ、Markdown記法の練習として、残します。

# 目次
[1.見出し](#1-見出し)
[2.リスト](#2-リスト)
    [2.1 番号付きリスト](#1-番号付きリスト)
    [2.2 番号なしリスト](#1-番号なしリスト)
    [2.3 チェックボックス](#1-チェックボックス)
    [2.4 nestの仕方](#1-nestの仕方)
[3.太字、斜字、打消し線](#3-太字、斜字、打消し線)
[4.コードの挿入](#4-コードの挿入)
[5.リンクの挿入](#5-リンクの挿入)
[6.引用](#6-引用)
[7.知っておくと便利なこと](#7-知っておくと便利なこと)




#1.見出し
見出しは先頭に「#+(半角スペース) 」をつけることで記述可能です。
\#の数によって見出しの大きさを変えることができ、h6の大きさまで指定できます。

>
# 見出しh1
\# 見出しh1
## 見出しh2
\## 見出しh2
>


##2.リスト
### 1.番号付きリスト
「1. 2. 3.」のように記述してもいいですし、「1. 1. 1.」としても自動的に連番で表示してくれるのでどちらでもいいと思います。
>
1.  
1.  
1. 

### 2.番号無しリスト
番号無しリストは「- + (半角スペース)」で記述できます。ただし後ろに何かしらの文字を書かないとつけることができません。
>
- practice 
- workout 
- homework
>

### 3.チェックボックス
チェックボックスは [(半角スペース)] で記述することができます。
ボックス内にチェックを入れたい場合は,**[x]**とすることで
留意しておく点として、Qiitaだとリストなしでのチェックボックスはできないのですかね。。

>
### To Do 
- [ ] to do 
- [x] hogehoge<br>
リストなしのチェックボックス↓<br>
[ ] このように表示される
>  


#3. 太字、斜字、打消し線
vs-code のプラグイン(拡張機能)で Markdown Oll in One を入れているとショートカットが使えます。(コマンドはMac環境)
### 太字 (Cmd + b) 
>
**moji**
\*\*moji\*\*
>

### 斜字(イタリック体) (Cmd + i ) 
>
*moji*
\*moji\*
>

### 打消し線
>
~~moji~~
\~\~moji\~\~
>

#4.コードの挿入
コードの挿入は基本的にはコード部分を　\`\`\`(バッククォート)3つで括ることです。

>
\`\`\`
def Hello():
    return "Hello"
\`\`\`
>
```
def Hello():
    return "Hello"
```

また、シンタックスハイライトを付けたい時は、言語名を指定するとその言語にあったハイライトがつきます(対応していない言語もあります)

>
\`\`\`python
def Hello():
    return "Hello"
\`\`\`
>
```python
def Hello():
    return "Hello"
```

よく見かける、左上にファイル名をつけるには、**言語名:ファイル名** とします
自分のvs-code だとこれで左上に名前がつかない現象が起きたのですが、なにか原因をわかる人がいましたら教えていただきたいです。。。

>
\`\`\`python:practice.py
def Hello():
    return "Hello"
\`\`\`
>
```python:pracitce.py
def Hello():
    return "Hello"
```

#5.リンクの挿入・画像の埋め込み

リンクの挿入は、\[リンクテキスト\](URL)でリンクをつけることができます。
>
\[YouTude\](https://www.youtube.com/?gl=JP)
のように書くと
[YouTude](https://www.youtube.com/?gl=JP)
>

画像の挿入は、!\[画像テキスト\](URL)で画像を出力できます。
>
!\[Machecster United\](https://pbs.twimg.com/profile_images/1225694132951076864/HHKUQE_5_400x400.jpg)

![Machecster United](https://pbs.twimg.com/profile_images/1225694132951076864/HHKUQE_5_400x400.jpg)
>

#6.引用
引用には、> をつけます
引用したい部分を > 引用部分　>　で囲むことでできます。

\>
引用
\>\>引用の引用
\>\>\>引用の引用の引用
\> 


>
引用
>>引用の引用
>>>引用の引用の引用
> 

#7.知っておくと便利なこと
知っておくと便利なこととして、Markdownでは**「\」**をつけるとそのマークダウンを無効化できます。

>
\\#hogeとすると,#hogeとなります。
>

改行は、
>
文字の後ろに**半角スペース2個** または \<br\>で出来ます。


その他また、追記事項があれば適宜追加して書いていきたいと思います。
第七回講義メモ

\![Mac OS X-10.15.7](<https://img.shields.io/badge/MacOSX-10.15.7-brightgreen>) \![ruby-2.6.3p62](<https://img.shields.io/badge/ruby-2.6.3p62-brightgreen>) 


# 条件分岐, Array


# 例題1

条件分岐を勉強していく上で, うるう年を例にあげる.

    入力がうるう年(leap year)かどうかを表示するプログラムをかけ．
    1. うるう年は4で割り切れる数の年．ただし，
    2. 100で割り切れる年はうるう年でなく，
    3. 400で割り切れる年はうるう年．
    4. 2004, 1999, 1900, 2000で試せ．
    5. それぞれtrue, false, false, true


# 一番簡単な条件分岐

rubyではif, elsif, else, endを使う.(以下例)

    if 式 [then]
      式 ...
    [elsif 式 [then]
      式 ... ]
    ...
    [else
      式 ... ]
    end

\*例題2引数として年を受け取り, 閏年か否かを判定するコードを書け.

実装

```ruby
p year = ARGV[0].to_i
if year%4 == 0
  p true
else
  p false
end
```

結果(2000, 1999)

    > ruby check_leap_2004.rb 2000
    2000
    true
    
    > ruby check_leap_2004.rb 1999
    1999
    false


# テストの自動化

テスト内容が増えた際はテストを自動化させたいし, その方が効率が良い.具体的には配列にして, loopで回すだけ.

```ruby
[2004, 1999].each do |year|
  p year
  if year%4 == 0
    p true
  else
    p false
  end
end
```


# case

caseを使って, より短いコードで実装を目指す.caseの動きは以下を参考.(<https://docs.ruby-lang.org/ja/2.5.0/doc/spec=2fcontrol.html#if>)

```ruby
case [式]
[when 式 [, 式] ...[, `*' 式] [then]
  式..]..
[when `*' 式 [then]
  式..]..
[else
  式..]
end
```

これを用いると以下のように書くことができる.

```ruby
def leap?(year)
  case
  when year % 400 ==0 ; return true
  when year % 100 ==0 ; return false
  when year % 4 ==0 ;   return true
  else ;                 return false
  end
end
```


# 参考サイト

<https://qiita.com/daddygongon/items/a550bde1ed6bff5217d8>



------
 - **source** ~/my_ruby/grad_members_20f/members/drop-sd/lectures/no7.org
書籍「文章は接続詞で決まる」まとめ　その１

「考える技術・書く技術」に代表されるような、文書の全体構造について書かれた書籍は多い。例えば、「考える技術・書く技術」で提唱されている文章のピラミッド構造では、まず、文書全体をひとつのピラミッドで構成し、一番伝えたいことをピラミッドのトップに配置する。そして、ピラミッドのボトムの各段落で詳細を説明する、という構造となっている。ピラミッド構造で文書を構築することで書き手の考えの整理になるとともに、読み手にとってもわかりやすい文書となる。
しかし、ピラミッド構造で文書を構築したとしても、実際に各段落の中身を書く際に上手く書けないことが多い。それは、各段落の中身について書き手の考えが整理されていないためである。各段落の中身の文章を整理するためには、接続詞を適切に用いて論理を明確にすることが重要である。「文章は接続詞で決まる」は接続詞について深く掘り下げた書籍で、接続詞の全体像や各接続詞の使用方法や効果について詳しく書かれている。

今回は書籍「[文章は接続詞で決まる](https://www.amazon.co.jp/dp/433403473X/)」をまとめてみた。

# 第一章　接続詞とは何か
* 接続詞とは、独立した先行文脈の内容を受けなおし、後続文脈の展開の方向性を示す表現である。
* 接続詞は、論理学のような客観的な論理ではなく、文脈の関係を書き手がどう意識し、読み手がどう理解するのか、という解釈の論理である。
* 例えば、接続詞「そして」には「そして」の、「しかし」には「しかし」の固有の論理がある。しかし、その論理は論理学のような客観的な論理ではなく、前後の文脈の背後にある論理をどう読み解くかを示唆する解釈の論理である。
* 人間が言語を理解する際は、文字から得られる情報だけではなく、文字から得られる情報を手掛かりにさまざまな推論を行いながら理解している。接続詞は、その推論のヒントとなる。

# 第二章　接続詞の役割
* 接続詞は読者の理解や印象に特に強い影響を及ぼす。
* 接続詞の機能は以下の6通りある。
    * 連接関連を表示する
    * 文脈のつながりをなめらかにする
    * 重要な情報に焦点を絞る
    * 読み手に含意を読み取らせる
    * 接続の範囲を指定する
    * 文章の構造を整理する

# 第三章　論理の接続詞
* 接続詞を、大きく以下の4種10類に分類する。
    * 論理の接続詞
        * 順接の接続詞（だから系、それなら系）
        * 逆説の接続詞（しかし系、ところが系）
    * 整理の接続詞 
        * 並列の接続詞（そして系、それに系、かつ系）
        * 対比の接続詞（一方系、または系）
        * 列挙の接続詞（第一に系、最初に系、まず系）
    * 理解の接続詞 
        * 換言の接続詞（つまり系、むしろ系）
        * 例示の接続詞（たとえば系、とくに系）
        * 補填の接続詞（なぜなら系、ただし系）
    * 展開の接続詞
        * 転換の接続詞（さて系、では系）
        * 結論の接続詞（このように系、とにかく系）
* 「だから」系：原因―結果の橋渡しに活躍
    * 先行文脈と後続文脈が原因―結果の関係にあることを明示し、それによって文書の説得力を高める働きがある。
    * 原因―結果の因果関係の知識は、読み手が一般的知識として持っていることが前提となる。
* 「しかし」系：単調さを防ぐ豊富なラインナップ
    * 順接の「こうなればこうなる」という前提に反することを予測する表現。「こうなってもこうならない」ということを表す。
    * 「しかし」のかわりに使える逆説の接続詞には、「だが」「でも」「それでも」「ただ」がある。
    * これらは、「しかし」の単調さを防ぐ豊富なラインナップとなる。
* 「ところが」系：強い意外感をもたらす
    * 想定外の展開を表す接続に使う接続詞。
    * 同系統の「にもかかわらず」は、硬い文章でよく使われる接続詞。先行文脈から考えて、そうなるのが当然の理である。しかし、現実はそうはならないという流れを表す。

# 第四章　整理の接続詞
* 「そして」系：便利な接続詞の代表格
    * 添加の接続詞とも呼ばれ、最後にひとつ、大切な情報を付け加える働きがある。
    * もともと、帰着点を表す「そうして」に由来する。
    * 同系統の「それから」は「そして」とは異なり、ひとつだけでなく何度も重ねて使うことでいくつもの情報を付け加えることができる。
* 「それに」系：ダメを押す
    * 累加の接続詞とも呼ばれ、「それだけでなく、まだ他にもある」という、すでに示したものに重ねて示す働きがある。
    * 同系統に「それにくわえて」「そればかりか」「そのうえ」「しかも」「ひいて」などがある。
* 「かつ」系：厳めしい顔つきで論理づけ
    * 「AかつB」で、AもBも両方同時に満たすことを意味する。法律の条文や論文など、論理を明確にしたい文書に使われる。
* 「一方」系：ふたつの物事の相違点に注目
    * 対立を表す接続詞。同系統に「他方」「それにたいして」「反対に」「反面」「逆に」がある。
    * 「一方」が一番よく使われる。それは、「それにたいして」や「反対に」などより、前後の関係を制約する程度が低く、使いやすいためである。
    * 「一方」は前後でなんらかの点で違っていれば使える。
    * 逆に、「反対に」や「逆に」は、前後の文脈の内容が文字通り反対でなければ使えない。
* 「または」系：複数の選択肢を示す
    * 選択を表す接続詞。同系統に「もしくは」「ないしは」「あるいは」「それとも」がある。
    * 「AまたはB」で、AかB、いずれか一方を選ぶことを意味する。
* 「第一に」系：文書のなかの箇条書き
    * 列挙して整理する働きがある。「第一に…」「第二に…」「第三に…」のように、接続詞のなかに数字が入る。
    * 列挙される項目に時間的順序性はない。つまり、その出現順序を入れ替えても文意に矛盾が生じることはない。
    * ただし、情報の重要性という意味では「第一に…」に一番重要な項目が配置されるのが一般的である。
* 「最初に」系：順序を重視した列挙
    * 列挙して整理する働きがある。「第一に」とは異なり、列挙される項目に時間的順序性がある。
* 「まず」系：列挙のオールマイティ
    * 「第一に」系と「最初に」系の接続詞の両方の特徴を兼ね備えており、時間的順序性のあるもの、ないもの、両方に使うことができる。
パスワード強度を表示するjQueryプラグインを使ってみた

ユーザが入力したパスワードの強度を判定して表示するjQueryプラグインを見つけた。
使い勝手が良さそうなので自社アプリに組み込んでみた。
![パスワード プラグイン](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/86388fb3-ef57-bb83-581e-8ec714ed40d1.gif)
PwdMeasure というプラグインで [GitHub](https://github.com/wadackel/jquery-pwd-measure) から入手できる。
以下に特徴を引用する。

>・パスワードの強度をパーセント表示可能
・単一の入力フィールド、確認フィールドへの対応
・強度を示すラベルを詳細に設定可能
・必要最低限のパスワード強度をパーセント指定可能
・判定をクリアした時、値が変わった時などのコールバックをサポート
・スタイルシートで自由にデザインを変更可能

使い方は公式ドキュメントを参照してもらうとして、組み込み方法を簡単に説明する。

# HTML
パスワードを入力する`<input>`要素に、強度を表示する要素を付け足すだけ。

```html
<p id="pm-indicator" class="pm-indicator"></p>
<div class="form-group">
    <label for="passwd" class="control-label col-sm-4">新しいパスワード：</label>
    <div class="col-sm-8">
        <input type="password" id="passwd" name="passwd" value="" class="form-control" autofocus>
    </div>
</div>
```

最近のブラウザは、テキストボックスの下にドロップダウンリストで入力候補を表示するため、強度を表示する要素はテキストボックスの上に配置した方が良さそうだ。

# JavaScript
jQueryの後に`jquery.pwdMeasure.min.js`を追加し、先ほどの`<input>`要素に対して`pwdMeasure`を実行するだけ。

```html
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="http://localhost:8000/js/jquery.pwdMeasure.min.js"></script>
<script type="text/javascript">
$(function(){
    $('#passwd').pwdMeasure();
});
</script>
```

CSSは公式のサンプルをそのまま使わせて頂いた。
初めてDockerを使ってみた

Dockerの勉強を始めました。これらの知識を忘れないようにメモとして残します。なお、本投稿はUbuntu20.04上で動作することを前提として書いています。

#Dockerのインストール
下のコマンドでDockerをインストールできます。

```console:
$ apt install docker docker-compose
```

#イメージ関連

他の人が作成したイメージをDockerHubからダウンロードができます。これにより自分で作る必要がなくなります。

* DockerHubに置いてあるイメージを探す

この`NAME`欄に書かれている名前がイメージ名です。

```console:
$ docker search nginx                         #nginxを探す
$ docker search -f is-official=true nginx     #公式のみ検索する場合
NAME                               DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
nginx                              Official build of Nginx.                        14228               [OK]                
```

* イメージをローカルにダウンロードする

ここで入力する名前は、先のイメージ名を使ってください。

```console:
$ docker image pull nginx     #イメージ(nginx)をダウンロードする
```

* ローカルにダウンロード済みのイメージを調べる

```console:
$ docker image ls
```

* ローカルにダウンロード済みのイメージを削除する

```console:
$ docker image rm nginx     #nginxのイメージを消す
$ docker image prune -f     #使用していないイメージをすべて消す
```

#コンテナの起動・停止・削除

イメージをダウンロードしたら、そのイメージからコンテナを作成します。

* コンテナの実行

コンテナを作成し実行します。
`--rm`はコンテナが終了すると同時にコンテナを削除します。
`--it ～～ bash`はコンテナ実行直後にbashを実行してキーボード入力を受け付けます。
`--name`はコンテナに名前を付けます。
`-d`はコンテナをバックグラウンドで実行し続けます。

```console:
$ docker container run --rm -it nginx bash                  #コンテナを作成・実行し、そのコンテナにbashで入り、bash終了後はコンテナを破棄する
$ docker container run --name websv -d nginx                #バックグラウンドでwebsvというコンテナ名で実行し続ける
```

* コンテナの検索

作成したコンテナを検索します。

```console:
$ docker container ls        #現在実行中のコンテナのみ表示する
$ docker container ls -a     #停止しているコンテナも表示する
```

* コンテナの停止

```console:
$ docker container stop websv
```

* コンテナの再開

```console:
$ docker container restart websv
```

* コンテナの削除

```console:
$ docker container rm websv     #コンテナ名websvを削除する
$ docker container prune -f     #停止しているコンテナを全て削除する
```

#実行中のコンテナへの操作

バックグラウンドで動いているコンテナに対し操作を行います。

* コンテナでシェルを実行する

```console:
$ docker container exec -it websv bash                   #コンテナwebsvにbashで入る
$ docker container exec websv bash -c "echo 'Hello'"     #コンテナwebsvでechoコマンドを実行する
```

* コンテナの標準出力を見る（ログを見る）

公式のnginxイメージではアクセスログは標準出力に出ます。（コンテナからデータを取り出す必要はありません。）

```console:
$ docker container logs websv
```

#コンテナ起動時のオプション

コンテナの起動オプションには、便利なものがたくさんあります。

* ポートフォワード

`-p`を使えばホストに入ってきた通信をポートフォワードしてコンテナに渡すことができます。下の例ではホストのTCP8080に来た通信をコンテナのTCP80に転送しています。なおUDPを受ける場合には、`-p 514:514/udp`と書きます。(syslog:UDP514の例)

```console:
$ docker container run --name websv -d -p 8080:80 nginx
```

* ファイルのマウント

ホストに置いてあるファイルやフォルダをコンテナにマウントします。下の例ではホストの`/home/hoge/index.html`でコンテナの`/usr/share/nginx/html/index.html`を置き換えています。なお`readonly`を付けることにより、コンテナ側からホスト上の`index.html`への書き込みを禁止しています。

```console:
$ docker container run -d --name websv -p 8080:80 --mount type=bind,src=/home/hoge/index.html,dst=/usr/share/nginx/html/index.html,readonly nginx
```

#さいごに

色々調べてやっと簡単なページを作れるまでに至りましたが、まだまだ先が長そうです。
curlコマンドでダウンロードしたい


デフォルトでMacにもWindowsにも`wget`コマンドがない・・・インストールするのは面倒くさい・・・ブラウザ起動するのも面倒くさい・・・けどコマンドでダウンロードしたい時

|オプション|意味|
|:-:|:--|
|-O|ファイルをダウンロードする|
|-L|URL先にリダイレクトがかかってたらリダイレクトする|

```bash
$ curl -OL {ダウンロードするURL}
```
第六回講義メモ

\![Mac OS X-10.15.7](<https://img.shields.io/badge/MacOSX-10.15.7-brightgreen>) \![ruby-2.6.3p62](<https://img.shields.io/badge/ruby-2.6.3p62-brightgreen>) 


# Variable, Method

第6回目では変数とメソッドについてまとめる. 


# 例題1

受け取った引数を, nameという変数に代入し, それを吐き出すcodeを書くこと.(rubyでは引数に, ARGV[0]を用いる.)

    > ruby name_variable.rb ruby
    ruby

rubyではpythonと同様に型宣言の必要がなく, イコールで代入される.

```ruby
name = 'ruby'
```


# 例題2

受け取った引数にhelloをつけて返すmethodを作ること.

```ruby
def hello(name)
  puts "Hello #{name}."
end
name = ARGV[0]
hello(name)
```

helloというメソッドを作成し, 引数を代入している.

結果

    > ruby hello_method.rb Rudy
    Hello Rudy.


# メソッド補足

Rubyではfunctionやprocedureなどのまとまりはmethodを定義(definition)することができる．methodは0個以上の引数(argument)を取ることが可能．(以下例)

```ruby
def hello(name)
  p name
end
```


# 参考サイト

<https://qiita.com/daddygongon/items/c51f3e0695174bb3c508>



------
 - **source** ~/my_ruby/grad_members_20f/members/drop-sd/lectures/no6.org
第五回講義メモ

\![Mac OS X-10.15.7](<https://img.shields.io/badge/MacOSX-10.15.7-brightgreen>) \![ruby-2.6.3p62](<https://img.shields.io/badge/ruby-2.6.3p62-brightgreen>) 


# Hello World

第一歩目, Hello Worldを出力してみる.

    Hello World


# 出力方法

| method   | できること        |
|:---------|:------------------|
| print    | 出力(要改行)      |
| puts     | 出力(自動改行)    |
| p        | デバッグ用        |
| pp       | デバッグの出力?   |
| printf   | Cと同じ           |


# puts

シングルコーテーションで括って,(シングル, ダブルどちらでも良さそう?)(追記) : Stringはシングルコーテーション'で囲うのと，ダブルで囲うのの二種類があります．シングルは中身をいじらないとき，ダブル"はちょこちょこいじるときです

```ruby
puts 'Hello World'
```

出力コマンド(保存したrubyファイルを指定)

    ruby puts_hello_world.rb

結果

    Hello World


# 参考サイト

<https://qiita.com/daddygongon/items/c51f3e0695174bb3c508>



------
 - **source** ~/my_ruby/grad_members_20f/members/drop-sd/lectures/no5.org
PlatformIOでESP32のSPIFFSにファイルを書き込むコマンド

#はじめに
マイコンであるESP32ファミリ（M5Stackなど）を使っていて、WIFIのSSIDやアプリの固定値をプログラム内に記述するのではなく、外出ししたい場合があると思います。この時、SPIFFS（SPIで接続されたメモリ上のファイルシステム）を使うのがお手軽です。

Arduino IDEでは、SPIFFSにファイルをアップロードする機能がメニューから選べますが、PlatformIOでどのように行うか調べたので説明します。

#PlatformIOでSPIFFSにファイルをアップロードする方法
以下の手順に沿って任意のファイルをSPIFFS上にアップロードします。

1. PlatformIO上でプロジェクトを開く
2. プロジェクト直下に data という名前で新しいフォルダーを作成する
3. dataフォルダ配下にアップロードしたいファイルを作成する
4. ESP32をUSBに接続する
5. ターミナルを開き、以下のコマンドを実行する  
   pio run --target uploadfs

※ダウンロード状態を示す表示が100%になり、数秒してコマンドが終了すれば転送が終わっています。
#おわりに
ターミナルを起動した際、操作したいプロジェクトのホームフォルダになっているか、プロンプトメッセージを確認しましょう。

Happy Making!
getElementByIdとqueryselectorの表記の違い

こんにちは。

今日はJavascriptのDOMで使用するgetElementByIdとqueryselectorの表記の違いについて備忘録として書いておこうと思います。


##getElementByIdは('')内に何もいらないが、querySelector('')はidなら#、classなら.が必要

例えば以下のような変数の宣言であれば、問題なく書くことが出来ますが、

 ```
const heading =document.getElementById('heading');
const text =document.getElementById('text');
```

以下のような形ではエラーになります。

```
const hide = document.querySelector('switch');
const familyList =document.querySelector('famiy');
```
querySelector()には必ず()内に「#」が「.」が必要なためですね。

簡単なことではあるのですが、初心者のため知らなかったので今回知れて良かったです。
拗音・促音（ｧｨｩｪｫｬｭｮｯ）を修正するコード

※初投稿です。お手柔らかにお願いします。

古いシステムなんかだと、銀行の口座名義に拗音（ｧｨｩｪｫｬｭｮ）や促音（ｯ）が使われていると支払処理を受け付けてくれない場合があります。

私の勤めている会社のシステム（SQLserver）がまさにそれで、手入力の場合には拗音・促音は受け付けないのですが、コピペなどだとすり抜けて入ってしまい、いざ支払処理をかけたらエラーが出る・・・（銀行にもよる）といったことが少なからずありました。
また、今後の予定として、システムに登録するための書類（Excelで作成）からデータを抜き出し、`pyodbc`でSQLserverにダイレクトに転記させたいので、遅くともその時点で拗音・促音を修正しておかないと同じ轍を踏むことになることからそんなコードを書く必要が生じ、思い付きで書いたらまあそれなりにうまくいったという次第です。

そんなわけで、あまり需要がないかもしれませんが、せっかく書いたこちらでQiitaデビューさせていただきます！


```python:コード
you_soku = 'ｧｨｩｪｫｬｭｮｯ'
print('変更前-->', you_soku)    # 確認用

ys_dict = {'ｧ': 'ｱ', 'ｨ': 'ｲ', 'ｩ': 'ｳ', 'ｪ': 'ｴ', 'ｫ': 'ｵ', 'ｬ': 'ﾔ', 'ｭ': 'ﾕ', 'ｮ': 'ﾖ', 'ｯ': 'ﾂ'}
for ys in ys_dict.keys():
    while ys in you_soku:
        you_soku = you_soku.replace(ys, ys_dict[ys])
print('変更後-->', you_soku)    # 確認用
```

```python:出力結果
変更前--> ｧｨｩｪｫｬｭｮｯ
変更後--> ｱｲｳｴｵﾔﾕﾖﾂ
```

拗音・促音の辞書をループさせ、キーが対象文字列内（上記の場合`you_soku`に格納されている文字列内）にある限り、そのキーに対応した文字（バリュー）を置換させるようにしてあります。
お気づきの方もいらっしゃると思いますが、ネストされている対象文字列の変数（上記の場合`you_soku`）を変えてしまうと、無限ループしてしまいます。。（実はやった口ですｗ）


実際にありそうな口座名義で試してみます。
もちろん、架空の方です。（軽く某ロックミュージシャンっぽい名前ですが、特にファンではございません。）

```python:コード
account_name = 'ｷｯｶﾜ ｼｮｳｼﾞ'
print('変更前-->', account_name)    # 確認用

ys_dict = {'ｧ': 'ｱ', 'ｨ': 'ｲ', 'ｩ': 'ｳ', 'ｪ': 'ｴ', 'ｫ': 'ｵ', 'ｬ': 'ﾔ', 'ｭ': 'ﾕ', 'ｮ': 'ﾖ', 'ｯ': 'ﾂ'}
for ys in ys_dict.keys():
    while ys in account_name:
        account_name = account_name.replace(ys, ys_dict[ys])
print('変更後-->', account_name)    # 確認用
```

```python:出力結果
変更前--> ｷｯｶﾜ ｼｮｳｼﾞ
変更後--> ｷﾂｶﾜ ｼﾖｳｼﾞ
```

本来であれば、このようなコードを使わずに済むよう、システム側で対応すべきなんですがね。
まあ言ってても始まらないので、書いてみました。

ご指摘・ご意見、大歓迎です。
まだまだ見習いですので、忌憚なくツッコミを入れていただければと思います。
Mysqlでユーザの作成と権限の付与をひとまとめで行った際に発生するエラーに関して

Mysqlの参考書を勉強中に下記問題に遭遇しました。
#問題
下記コードは、権限を付与するGRANT文を使ってユーザの新規作成も同時に行うというものです。

``` grant all privileges on basic.* to myusr@localhost identified by '12345';```

しかし、これを実行したところ下記エラーが発生しました。

```ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'identified by '12345'' at line 1```

#原因
調べたところバージョン8以降はユーザ作成と権限付与を同時に行うことは出来なくなっているというものでした。

#解決策
バージョン8以降は

１、ユーザの作成
```CREATE USER user IDENTIFIED BY '12345';```
２、権限の付与
```grant all privileges on basic.* to myusr@localhost;```

と、ユーザ作成と権限の付与を分ける必要があるそうです。
SlackのIncomingWebhookにNuxt.js+axiosでメッセージを送る

# やりたいこと
何気にやったことがなかったSlackのIncomming Webhookを叩くという処理をやってみる

# 環境
nuxt.jsとaxiosを使ってやってみます

```
% sw_vers
ProductName:    Mac OS X
ProductVersion: 10.15.7
BuildVersion:   19H2

% docker version
Client: Docker Engine - Community
 Cloud integration: 1.0.1
 Version:           19.03.13
 API version:       1.40

# npm -v
6.14.8

# npx nuxt -v
@nuxt/cli v2.14.12
```

# Incoming Webhookを有効にする
まずは準備。
slackの指示通りに設定します
すると後に使う*webhookURL*が発行されます

# 実装
## npm install
`axios`を使って送信します
また、webhookURLは`.env`に記述するので`dotenv`もインストールします

```shell

$ npm install @nuxtjs/axios @nuxtjs/dotenv
```

```json:package.json
{
  "name": "api_practice",
  "version": "1.0.0",
  "private": true,
  "scripts": {
    "dev": "nuxt",
    "build": "nuxt build",
    "start": "nuxt start",
    "generate": "nuxt generate"
  },
  "dependencies": {
    "@nuxtjs/axios": "^5.12.2",
    "@nuxtjs/dotenv": "^1.4.1",
    "@nuxtjs/pwa": "^3.0.2",
    "bootstrap": "^4.5.2",
    "bootstrap-vue": "^2.17.3",
    "core-js": "^3.6.5",
    "nuxt": "^2.14.6"
  },
  "devDependencies": {}
}

```


## edit index.vue
ボタンを押せば'テストメッセージですの'がslackに投稿されます

```javascript:index.vue
<template>
  <div class="container">
      <button @click="send">slackに送信</button>
  </div>
</template>

<script>
const axios = require('axios');

export default {
  methods: {
    send: function () {
      let params = new URLSearchParams();
      let message = {text: 'テストメッセージですの'}
      params.append('payload', JSON.stringify(message));
      axios.post(process.env.SLACK_URL, params).then(res => {
        console.log(res);
      }).catch(err => {
        console.log(err);
      });
    }
  }
}
</script>

```

slackの仕様が最近変わったらしく、メッセージをpayloadというプロパティに入れる必要があるみたいです
またpostで送る際にCORF?エラーが出るため、axiosのドキュメントを参考にURLSearchParamsを使用しました
synchronizedとReentrantLockについて(Java&Kotlin実装例)

# synchronizedとは
そもそもJavaでは特定のオブジェクトに関する操作をスレッドセーフにするために`synchronized`という修飾子が用意されています。
例えば以下のように付与します。

```Data.java

public class Data {
    int x = 0;
    int y = 0;

    public synchronized void inc() { // synchronized method
        x += 1;
        y += 1;
    }

    public void dec() {
        synchronized (this) { // synchronized statement
            x -= 1;
            y -= 1;
        }
    }
}
```

`synchronized`が付与されたメソッドを定義すると、メソッドの呼び出し元のスレッドがこのインスタンス(この場合Dataインスタンス)に対してロックを取ります。一度ロックが取得されると、ロックが開放されるまで他のスレッドがこのインスタンスに対するロックを必要とする処理をブロックされるようになります。使い方にはsynchronized methodとsynchronized statementの2種類があります。

上記のinc()メソッドとdec()メソッドはそれぞれx,yに1を加える/引くメソッドなのですが、synchronizedによって同期を取らないと複数のスレッドからの呼び出しによって**xとyの値が異なる**状態が発生し得ます。

これはJavaプログラマーにおいてはかなり重要な要素なのですが、Kotlinではsynchronized修飾子は用意されていません。その代わり、@Synchronizedアノテーションとsynchronizedインライン関数が用意されています。

[https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-synchronized/:title]

```Data.kt

class Data(var x: Int, var y: Int) {
    @Synchronized
    fun inc() {
        x += 1
        y += 1
    }
    
    fun dec() {
        synchronized(this) {
            x -= 1
            y -= 1
        }
    }
}
```

これでほぼ等価なJavaとKotlinで互換したコードが書けましたね。

# ReentrantLockについて

ReentrantLockとは、java.util.concurrentに収められている並列処理のためのロック機構です。
`synchronized`と似たような同期を実現することができます。

利用する時はReentrantLockのインスタンスを生成し、lock()とunlock()によって取得と開放を行います。
他のスレッドがロックを取得していた場合はlock()でブロックされます。
unlock()がされないことがないように、JavaDocにはtry-finallyを使用することが勧められています。

```Data.java
public class Data {
    int x = 0;
    int y = 0;
    Lock lock = ReentrantLock(true);

    public void inc() {
        lock.lock();
        try {
            x += 1;
            y += 1;
        } finally {
            lock.unlock()
        }
    }
}
```

Kotlinの場合はもっとスマートに、withLockインライン関数を用いて以下のように書くことができます。
withLockではブロック内に入る前にロックが取得され、出る際にロックが開放されます。

```Data.kt
class Data(var x: Int, var y: Int) {
    val lock = ReentrantLock(true)
    fun inc() {
        lock.withLock {
            x += 1
            y += 1
        }
    }
}
```

# メリット・デメリット

結局どちらの実装で同期を取るのがベターなのでしょうか。
それを知るには以下に目を通すとよいでしょう。
https://www.ibm.com/developerworks/java/library/j-jtp10264/
https://stackoverflow.com/questions/11821801/why-use-a-reentrantlock-if-one-can-use-synchronizedthis

ReentrantLockを使用するべきなのはどのような場合か？という問に対して、以下のように答えています。
> The answer is pretty simple -- use it when you actually need something it provides that synchronized doesn't, like timed lock waits, interruptible lock waits, non-block-structured locks, multiple condition variables, or lock polling. 

勝手に日本語訳をつけると以下のようになります。

> 答えは極めて単純、`synchronized`ができないことが必要になったときだ。例えばタイムアウト付きwait、割り込み可能なwait、ブロック構造でないロックの書き方、複数の条件変数、ロックの状態確認など。

結局どちらを選ぶべきかという議論に対して、synchronizedはスレッド間の同期に最低限の機能を提供しているから十分だと言うこともできるし、より柔軟な同期機能を利用したいがためにReentrantLockを利用するのもありということですね。

# あとがき
かなり古い本で勉強していたらjava.util.concurrentのAPIについてほとんど触れられていなくて、今風の実装を調べ直す羽目になりました。とはいえJ2SE5.0が出たのが2004年9月30日だそうで、Java界隈にはjava.util.concurrentに関するノウハウがかなり蓄積されていることだと思います。
GithubでUnityプロジェクトの管理方法

UnityプロジェクトをGithubで管理する方法を知りませんでしたので、調べて設定した事をまとめました。

__Github・Unity・Sourcetreeがインストールor登録されている状態__からの連携になります。

__GithubでUnityプロジェクトの管理をする方法__
①Githubを開き、リポジトリタブを選択する
![61B03EC6-2585-4BDB-8229-8161856F21E9_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/6d6b943e-68a9-5226-dec2-452b1efc91ea.jpeg)


②Newボタンから新規のリポジトリを作成する
![DF345EBC-A133-4C87-9B52-0FCE09C0C32B_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/c56e5d7c-1b7f-1df4-0fa8-ebce230b446f.jpeg)


③リポジトリの名前を入力する（作成するゲームに関連する名前を付ける）
![FFDA43A2-67D6-4A88-B96B-A79020CC5610_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/1292b599-08f2-6c08-6f84-3fc02645e70c.jpeg)
![5BF255EF-A9BB-4E21-B7A4-7956CEF90AC6_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/a3f037c0-9232-f1df-53d4-055c02cc7afe.jpeg)



④AddignoreでUnity用の無視ファイルを選択をする
![5EE8D5E8-3A47-42D3-8489-C67B5214AD5A_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/cd78606e-d92a-2fea-83a8-1f87bdcd28cb.jpeg)


⑤クリエイトリポジトリを押す

⑥Sourcetreeにリモートリポジトリが作成されているのを確認し、クローンを押す

⑦保存先のパスの部分に保存先を指定する。（作成するリポジトリ名が消えている事があるので消えている場合は、　/Unity・・など追加してあげる）
指定できたらクローンを押す

⑧Unityhubから、新規でUnityプロジェクトを作成する

⑨上記のUnityプロジェクトのフォルダ と リポジトリクローンのフォルダをどちらも開き、リポジトリクローんのフォルダに全てドラッグ＆ドロップする
（ドロップさせたらUnityフォルダは必要ないので削除してOK）
（Unityhubの空になったプロジェクトも削除してOK）

⑩Unityhubのリストから追加からリポジトリクローンのフォルダを指定し、プロジェクトを作成。

11、Sourcetreeを確認するとリポジトリに追加できる状態になっているので、チェックボックスに全てチェックをしコミットする。

１２、コミット完了後、ブランチを選択してPUSHする。

おわり
CSSのhover, activeの色を簡単に対応する

# CSSのhover, activeの色を簡単に対応する
「デザインファイルをいただいたものの、Hover, Active時のカラーがない‼」
「いろんな色を使ってるのでHover, Activeの色まで定数化したら大変なことになる」
みたいなときありませんか？僕はあります。そんな時に雑に使える色を変えるテクニックがこちら

```scss:style.scss
button {
  background: $primary-color;
　color: $white-primary
  &:hover {
    filter: brightness(90%);
  }
  &:active {
    filter: brightness(80%);
  }
}
```

CSSのフィルター機能で全体的にちょい暗くするCSSです。これなら色が変わろうが中が画像だろうがなんでも対応できます。
難点は以下の通りIEに対応していないというところ…今時IEなんて対応するプロダクトあるはず…うっ…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253700/01284d4e-ad2c-5fc1-7b11-b8a4ae9b82df.png)
ABC161D Lunlun Number with python3

#[ABC161D Lunlun Number](https://atcoder.jp/contests/abc161/tasks/abc161_d)

##正解コード
```
import queue
q = queue.Queue()
for i in range(1,10):
    q.put(i)
K = int(input())
for k in range(K):
    x =q.get()
    last = x % 10
    if last != 0:
        q.put(10*x + last - 1)
    q.put(10*x + last)
    if last != 9:
        q.put(10*x + last + 1)
print (x)
```

##考え方
1から９のルンルン数から末尾に一の位の数との差が１以下である数を付け足して新たなルンルン数を生成していく。そして生成されたルンルン数からまた新たにルンルン数を生成していく。K個目のルンルン数が生成されたら処理を終了する。

##ポイント1
K個のルンルン数全てをリストに格納するとメモリをめちゃくちゃ食うことになる。
そこで、リストの代わりにqueueを使うと新しくルンルン数を生成し終わった用済みのルンルン数をget関数でメモリから追い出していくことができる。

##ポイント２
今回の問題では１の位が0か9かそれ以外かで場合わけする必要がある。場合わけはできるだけ完結に書きたい。
恥ずかしい限りだが自分は最初次のように書いていてしまった。

```
if last==0:
    q.put(10*x + last)
    q.put(10*x + last + 1)
elif last==9:
    q.put(10*x + last)
    q.put(10*x + last - 1)
else:
    q.put(10*x + last)
    q.put(10*x + last - 1)
    q.put(10*x + last + 1)
```
こうならないためには同じ処理を２度書かないということを意識すればいい。
場合に対して処理を書くのではなくある処理をどの場合に行うかを考えると自然に綺麗なコードになる。

##まとめ
queueを使うとメモリ削減になる！
場合分けは処理->場合の流れで考えろ！
SQLのデータ型について

# はじめに

今回はSQLのデータ型の種類について改めて学習したので
こちらも忘れない様アウトプットとして記していこうと思います。

# 主な種類

- 整数

- 実数

- 文字列

- 真偽値

- 日時


# 整数

|  データ型　| 扱える数の幅 |
|:-- |:-- |
| TINYINT | -128 ~ +127|
| INT     | -21億 ~ 21億 |
| SMALLINT     | -83万 ~ 83万 |
| MIDINT     | -83万 ~ 83万 |
| BIGINT  | -922京 ~ 922京 |

UNSIGNEDは整数のみを扱い、扱える範囲が大きくなります。

| データ型　| 扱える数の幅　|
|:-- |:-- |
| TINYINT UNSIGNED| 0 ~ 255 |
| INT UNSIGNED| 0 ~ 42億|
| BIGINT UNSIGNED| 0 ~ 1844京　|

# 小数点を含む実数

| データ型| |
|:-- |:-- |
| DECIMAL| 固定小数点　|
| FLOAT | 不動小数点 |
| DOUBLE | 不動小数点(高精度) |

# 文字列

| データ型　| |
|:-- |:-- |
| CHAR(固定長) | 0 ~ 255文字 |
| VARCHAR(可変長) | 0 ~ 65535文字　|
| TEXT | それ以上|
| ENUM|　特定の文字列から1つ　|
| SET | 特定の文字列から複数　|

`固定長とは！`  入るデータの長さが決まっていること
　　（商品コードや郵便番号の文字列を固定のものを格納するときに使われる）

`可変長とは！`　入るデータが決まっていないこと
　　（氏名や書籍名といった文字列を格納するときに使われる）

### ENUMの書き方はこんな感じ

特定の文字列の中から一つだけを格納します。

```sql
DROP TABLE IF EXISTS posts;
CREATE TABLE posts (
  message VARCHAR(140), 
  likes INT,
  category ENUM('Gadget','Game', 'Business')
);

INSERT INTO posts (message, likes, category) VALUES 
    ('Thanks', 12, 'Gadget'),
    ('Arigato', 4, 'Game'),
    ('Merci', 4,'Business');

SELECT * FROM posts;
```

index番号を指定してあげても指定できます。

```sql
INSERT INTO posts (message, likes, category) VALUES 
  ('Thanks', 12, 1),  
  ('Arigato', 4, 2),  
  ('Merci', 4, 3);

SELECT * FROM posts;


--　この様な感じで出力される

+---------+-------+----------+
| message | likes | category |
+---------+-------+----------+
| Thanks  |    12 | Gadget   |
| Arigato |     4 | Game     |
| Merci   |     4 | Business |
+---------+-------+----------+
```

### SETはこんな感じで使う

複数を格納したい時に使用します。
`書き方`↓　(テーブルの作り方は上の書き方と一緒です。)

```sql

  categories SET('Gadget', 'Game', 'Business')
```

`登録`↓

```sql
INSERT INTO posts (message, likes, categories) VALUES 
  ('Tnanks', 12, 'Gadget,Game'),
  ('Arigato', 4, 'Business'),
  ('Merci', 4, 'Business,Gadget');
```

値を数値で管理しているのでそちらを指定してあげても指定できます。
（2の◯乗で管理されている）＝　2^0, 2^1, 2^2, ...  1, 2, 4, ...

```sql
INSERT INTO posts (message, likes, categories) VALUES 
  ('Tnanks', 12, 3),  -- 1 + 2    --Gadget,Game
  ('Arigato', 4, 4),  -- 4        --Business
  ('Merci', 4, 5);    -- 1 + 4    --Gadget,Business 
```
# 真偽値

| データ型　| |
|:-- |:-- |
| BOOL | TRUE / FALSE |
| TINYINT(1) | 1 / 0 |

   「TRUE」か「FALSE」、または「０」か「１」で登録します。


# 日時

| 　データ型| |
|:-- |:-- |
| DATE | 日付 |
| TIME | 時間 |
| DATETIME | 日時 |

 - 「'2020-10-11 15:32:05'」（時間を指定）
 
 - 「'2020-10-12'」(記入していない時間は00で出力される)
 
 - 「NOW()」（現在の日時）という感じで登録します。
 
この様に出力されます。

```sql
+---------+-------+----------+---------------------+
| message | likes | is_draft | created             |
+---------+-------+----------+---------------------+
| Tnanks  |    12 |        1 | 2020-10-11 15:32:05 |
| Arigato |     4 |        0 | 2020-10-12 00:00:00 |
| Merci   |     4 |        0 | 2020-12-31 14:13:42 |
+---------+-------+----------+---------------------+


```


# まとめ

今回ははじめとしてよく使うであろうデータ型の確認でした。

まだたくさんあると思いますので引き続き学習していきます。



# 参考

[【初心者向け】SQLのデータ型を理解しよう！利用方法も解説！](https://style.potepan.com/articles/24937.html)

[SQLserverテーブル作成時のデータ型についての備忘録](https://pctips.jp/server/data-type-memorandum201909/)
GASでGoogleForm送信時に飛ばすSlack通知が2回連続で来る

掲題の通り、GASでGoogleForm送信時にSlack通知を飛ばしたかった。
[こちらの記事](https://qiita.com/vmmhypervisor/items/18c99624a84df8b31008?fbclid=IwAR0Fw2jKqm5M1OZZQs4te3i6Uq4IiyQ8b-QK-I4faw5K2513jXBDGuhchL0)の通り設定したら通知は来るようになったのだが、2回連続で来るようになった。
これはこれで使えるのだが、2回も同じ内容が毎回飛んでくるとかなり鬱陶しい。
なのでこれを直そうと思って色々試してみたが、GASの仕様理解しないとかなり沼にハマるので残しておこうと思う。

## 結論
2回通知が来た原因は、GASのSimple Triggerで発火される関数をInstalled Triggerでも登録していたからだった。
[Simple Trigger](https://developers.google.com/apps-script/guides/triggers?fbclid=IwAR3SuyRIaJOSIdPC2-Y75kfMBCbKywgPhi3oVKsXLZrZChp05S6_shX5Z-w)
[Installed Trigger](https://developers.google.com/apps-script/guides/triggers/installable?fbclid=IwAR3hrnVWJkTnD15fFfg-eMbCNpLTbpRrvmKxyzjCV2r9ofkuKHxOlRlU3Ow)


#### Simple Triggerとは
ある特定の関数名を定義しておくだけで発火するトリガーのこと。
例えばGoogleスプレッドシートを開いたタイミング、編集したタイミングでイベント発火させたい場合、それぞれ`onOpen(e)`,`onEdit(e)`といった関数を定義しておけば自動で発火してくれる。
今回はフォーム送信時だったので、`onFormSubmit(e)`だった。

#### Installed Triggerとは
イベント発火時に、特定の関数を呼び出すためのトリガーのこと。
下のモーダルから設定することが出来るが、こちらはSimple Triggerと違って発火させるイベントと発火させる関数を設定しておかないといけない。
逆に関数名の縛りはないので、自由にネーミング出来る。


フォーム送信時に通知が2回送られていたのは、Simple Triggerである`onFormSubmit(e)`をInstalled Triggerに登録していたからだった。
なので、`onFormSubmit(e)`という関数名を変更するか、トリガーを削除すればSlack通知は1回だけになる。

たったこれだけのことに半日くらい時間溶かした…。
Elasticsearch 用語・論理的な概念

#### 目的
Elasticsearch に関連する用語の内、論理的な概念のものについて整理する。
RDBなど他のデータベースとの違いなどを確認し、用語で混乱することが無いようにする。
![ELK_logical_word.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63951/ce3982ca-60d6-7ae9-89ac-fb822dae8b56.png)

#### Document (ドキュメント)
Elasticsearch に格納する1つの文章の単位。
RDB（リレーショナルデータベース）でいうレコード。
ドキュメントはJSONオブジェクトとして格納され、各ドキュメントを内部で管理するためのIDが付与される。
IDはインデックスへ格納時にユーザにより指定が可能だが、指定しなかった場合でも自動的に付与される。

#### Field（フィールド）
ドキュメント内で扱われる key:value のペアのこと。
ドキュメントは1つ以上のフィールドから構成される。
Elasticsearch における転置インデックスは、フィールドごとに作成・管理されるため、検索クエリ実行時は基本的にフィールド単位で実行される。

##### Fieldで扱われるデータ型の種類について
- 文字列(text, keyword)  
text 型: 格納時にアナライザ(Analyzer)によって文章を構成する各単語に分割されて、分割された単語ごとに転置インデックスが構成される。
そのため、text 型フィールドに対するクエリは単語を指定して検索する使い方になる。  
keyword 型: 格納した文字列を「完全一致」で検索する用途で使う。
（アナライザによる単語分割処理は行われない）

- 数値(long, short, integer, floatなど)
数値の大小や、Range（範囲）検索が可能。値の部分はダブルクォートで囲まない。

- 日付(date)
例) 
年月日 "2020-12-25"
年月日時分秒 "2020-11-04T18:00:10"
UNIXエポックからのミリ秒 "1587364200000" など
値はダブルクォートで囲む。

- 真偽(boolean)
true or false。値はダブルクォートで囲まない。

- オブジェクト(object)
object 型というデータ型を用いると、JSONオブジェクト自体をデータ型として扱うことが可能。
{"book":{"title":"ELK", "price":5000}}

- 配列(array)
数値 {"id":[3,4,5]}
文字列 {"alfabet":["A","B","C"]}
Object {"students":[{"name":"ken"},{"name":"Ami"}]}

##### マルチフィールドについて
Elasticsearch5.0以降、マッピング定義で型を明示的に定義していない状態で、文字列をインデックスに格納すると、そのフィールドはデフォルトで text と keyword 型のマルチフィールドとして定義されるようになっている。
この場合、多少インデックス容量が増加するので、用途が明確であれば、text or keyword 型を明示的に定義する方が望ましい。

#### Index(インデックス)
ドキュメントを保存する場所のこと。
Elasticsearchでは、格納したドキュメントがそのまま格納されるのではなく、検索を効率的に行うためにアナライザや転置インデックス情報などにより、さまざまな形式で保存される。
また、一定数のシャードと呼ばれる単位に分割されて各ノードに分散して格納されている。

#### Document Type(ドキュメントタイプ)
ドキュメントがどのようなフィールドから構成されているか？
ドキュメントに含まれるフィールドの型や属性情報などのデータ構造が定義されたものをドキュメントタイプと呼ぶ。
Elasticsearchバージョン 5.x までは、1つのインデックスに対して複数のドキュメントタイプを定義することが可能だったが、それ以降のバージョンでは不可となっている。

#### Mapping(マッピング)
ドキュメントタイプを具体的に定義したものとして、各フィールドのデータ構造やデータ型を記述した情報をマッピングと呼ぶ。
※RDBにおけるスキーマのようなもの
Elasticsearchでは事前にマッピングが定義されていない場合、Elasticsearchが各フィールドのデータ型を推測して自動的にマッピングを定義してからドキュメントを格納してくれる。
[Python] poetryを使用したPyPIパッケージ公開手順

# はじめに

[poetry](https://python-poetry.org/) を使用して、PyPIにパッケージを公開するための設定手順です。

PyPIそのものと、PyPIのアカウント登録については、@shinichi-takii さんの記事をご参照ください。

* [PyPIとは](https://qiita.com/shinichi-takii/items/e90dcf7550ef13b047b5#pypi-%E3%81%A8%E3%81%AF)
* [PyPIアカウント登録](https://qiita.com/shinichi-takii/items/e90dcf7550ef13b047b5#pypi%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E7%99%BB%E9%8C%B2)

# 準備

## poetryとkeyringをインストール

もしまだインストールされていなければ、poetryとkeyringをインストールします。
keyringは、PyPIのアカウント情報を保存するために使用されます（なくても大丈夫ですが、インストールする方がおすすめです。macOSの場合、キーチェーンを使ってくれます）。

poetryのインストールについては、@canonrock16 さんの記事をご参照ください。

* [【2020/06最新版】pythonの依存関係管理ツールpoetryの基本的な使い方](https://qiita.com/canonrock16/items/f77ee2a2df9be5b8cc37)

keyringのインストールについては、@hidelafoglia さんの記事をご参照ください。

* [python:keyringによるパスワード管理](https://qiita.com/hidelafoglia/items/cf84870dd7939524e3e9)



## テストレポジトリの登録

**testpypi**という名前で、Test PyPIのURLを登録します。

```console
poetry config repositories.testpypi https://test.pypi.org/legacy/
```

TestではないほうのPyPIは、poetry自体に組み込まれているので何もしなくてよいです。

## API Tokenの発行

[PyPI](https://pypi.org/manage/account/#api-tokens) および [Test PyPI](https://test.pypi.org/manage/account/#api-tokens) へアクセスし、API Tokenを発行します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59475/07e3759f-5890-2914-9a48-7f600f2302ce.png)

Add API tokenをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59475/70cc8c10-c306-4591-b6fe-d258054667d2.png)

任意のToken nameを入力し、Scopeを選択します。
Add tokenをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59475/b1ce0798-8a57-7e7d-5dc2-505ff98a46aa.png)

API Tokenが発行されるのでコピーします。

## API Tokenの登録

PyPIのAPI Tokenを登録します。

```console
poetry config pypi-token.pypi "PyPIのAPI Token"
```

Test PyPIのAPI Tokenを登録します。

```console
poetry config pypi-token.testpypi "Test PyPIのAPI Token"
```

# パッケージの作成

これからパッケージを作成する場合は、`poetry new パス名`というコマンドを実行すると、パスで指定したディレクトリの下に、以下のようなファイルが出来上がります。


```
├── README.rst
├── パス名
│   └── __init__.py
├── pyproject.toml
└── tests
    ├── __init__.py
    └── test_パス名.py
```

`pyproject.toml`ファイルを開き、以下の項目を`[tool.poetry]`セクションに追加します（追加しなくてもよいですが、追加するほうがおすすめです）。
readmeのファイル名は、実際に合わせてください。

```toml
[tool.poetry]
description = "短い説明文"
license = "ライセンス名"
homepage = "ホームページURL"
repository = "ソースレポジトリURL"
readme = "README.md"
```



`setup.py`ファイルは、ビルド時に自動的に生成されるので、自前で用意しなくても大丈夫です。

# パッケージをビルド

以下のコマンドを実行すると、distディレクトリ以下にソースtarボールとwhlファイルができます。

```console
poetry build
```

# パッケージをアップロード

Test PyPIへアップロードするには、登録したレポジトリ名を指定します。

```console
poetry publish -r testpypi
```

TestではないほうのPyPIへアップロードする場合は、何も指定する必要はありません。

```console
poetry publish
```

# おわりに

[poetry](python-poetry.org)を使うことで、Python初心者の自分でも簡単にパッケージを作成して公開することができました。
Lighthouse CIを使ってパフォーマンス品質を維持する(next.jsの例)

#Lighthouse CIを使ってパフォーマンス品質を維持する
## 概要
LighthouseというGoogle謹製のWebサイトのパフォーマンス計測ツールを使ったことある人は少なくないのではないでしょうか。

この記事ではそのLighthouseをCI上で実行してパフォーマンス品質を維持するテストのような動作をさせることができる「LighthouseCI」を使ってみます。

## 下準備

### 動かすサイトをでっちあげる
VueでもReactでもただのHTMLでもよいのですが、今回は計測対象のサイトをcreate-next-appで作成してみます。

```terminal
$ npx create-next-app
```

とりあえず使ってみたいのでとてもシンプルなNext.jsのアプリケーションを作成しました。

### LighthouseCIをローカルに導入
実際にCI上で動かすならローカルには必要ないのですが、試しに動かしたりしたいのでLighthouseCIをインストールします。

```terminal
$ npm install -g @lhci/cli@0.6.x
```

これで`lhci`コマンドが使えるようになりました。


### LighthouseCIの設定
次にLioghthouseCIの設定を行います。よくある設定ファイルを配置するタイプです。

```javascript:lighthouserc.js
module.exports = {
  ci: {
    collect: {
      numberOfRuns: 1,
      staticDistDir: "./out",
      url: [
        "/"
      ]
    },
    "assert": {
      "preset": "lighthouse:no-pwa",
    },
    "upload": {
      "target": "temporary-public-storage"
    }
  }
}
```

`next export`コマンドで生成されるSPAは`.out`ディレクトリに生成されるため、設定します。（デフォルトだとpublicとかになるはず）
urlという部分で計測対象のページを列挙します。今回はとりあえずRootページだけで設定します。

assertにはテストとして実行する値を設定します。ここにいろいろ書くことで値を細かく設定できるのですが、今回は面倒なのでpresetで実行します。（これはPWAでないもの全般に対応したものです）

uploadではテスト結果のレポートを何処かにアップロードする設定を書きます。
Google様は太っ腹なので`"target": "temporary-public-storage"`を指定すると、Googleの共有な何処かのサーバーに自動でアップロード、参照可能にしてくれます。社外秘とかでなければこの設定で申し分ない気がしています。

### CI(今回はGithubActions)で動作するように設定する
我らがGitHubは`.github/workflow`に設定ファイルを置くだけでCIのActionsを実行できます。神。

```yml:.github/workflow/ci.yml
name: lighthouseCI
on: [push]
jobs:
  lighthouseci:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-node@v1
      - run: npm install && npm install -g @lhci/cli@0.6.x
      - run: npm run build
      - run: npm run export
      - run: lhci autorun
```

これでpush時にbuild, exportをしてからlhciコマンドを実行してくれます。

## 使ってみる
準備が整ったので使ってみます。githubの適当なRepoにpushすると、GitHub上のActionsタブに実行中のアクションが出てきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253700/29abf652-0d7c-3ebc-c7ce-4029ea84de4e.png)

結果が出ました、何も弄ってないので結構いろいろと引っかかってるのですが、いろいろな項目に対してテストが走っていることが分かります。

下から5行目ぐらいのところにReportのURLが出ています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253700/ea5eeca7-1799-4e2f-faf0-c4ea735a0bd8.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253700/aeb5b8f8-59ca-f11c-67a8-f909961b2b6e.png)
イイ感じです。

設定のしようによってはPRの条件にしたり、Slack通知したりもできると思うので是非活用してみましょう。
【Android】KotlinでRoomデータベースとListViewを繋げてメモ帳を作成


####関連
前回記事:
KotlinでRoomデータベースを使用
https://qiita.com/clipbord/items/c7a12ec17412b10578fd

全ソース：
https://github.com/CoffCookie/memoList


####参考
https://techacademy.jp/magazine/32252
上記を参考に上記記事で作成したコードにListViewを組み込んでみた。

###ListViewのコード

```MainActivity.kt
        val data = arrayListOf("0")

        //配列にデータベースに保存したデータを取り出して保存
        for (memo in memoList) {
            data.add(memo.text.toString())
        }

        // リスト項目とListViewを対応付けるArrayAdapterを用意する
        val adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1,data)
        // ListViewにArrayAdapterを設定する
        val listView: ListView = findViewById(R.id.listView)
        listView.adapter = adapter
```

###View作成

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105573/71a6ebd9-6177-c113-45a1-544dc711fd0a.png" width="300" height="243" >


```activity_main.xml
    <EditText
        android:id="@+id/memoText"
        android:layout_width="270dp"
        android:layout_height="101dp"
        android:layout_marginStart="16dp"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="36dp"
        android:ems="10"
        android:inputType="textMultiLine|textPersonName"
        android:text="@string/memo_text"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/saveButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginLeft="16dp"
        android:text="@string/save_button"
        app:layout_constraintBottom_toBottomOf="@+id/memoText"
        app:layout_constraintStart_toEndOf="@+id/memoText"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="1.0" />

    <ListView
        android:id="@+id/listView"
        android:layout_width="321dp"
        android:layout_height="407dp"
        android:layout_marginTop="16dp"
        app:layout_constraintStart_toStartOf="@+id/memoText"
        app:layout_constraintTop_toBottomOf="@+id/memoText" />
```
オンプレGitLabで依存関係プロキシ(Dependency Proxy)を設定してDockerHubのダウンロード制限を回避する(設定編)

毎度、ググっても出てこない小ネタを取り扱っております。
本記事は個人的な見解であり、筆者の所属するいかなる団体にも関係ございません。

# 0. はじめに

GitLabのDependency Proxyの話です。
GitLab Premiumの機能でしたが、13.6(2020年11月)からCommunity EditionのCoreの無料版で使えるようになりました。
社内のオンプレGitLabに設定してみたという話になります。(GitLab.comでは2020年11月から利用可能になっています)

The Dependency Proxy is moving to open source | GitLab
https://about.gitlab.com/blog/2020/10/30/minor-breaking-change-dependency-proxy/

Using the Dependency Proxy to improve your pipelines | GitLab
https://about.gitlab.com/blog/2020/12/15/dependency-proxy-updates/

# 1. Dependency Proxyについて

## 1-1. Dependency Proxyってなに？

簡単に言うと、DockerHubのDockerイメージをキャッシュしてくれるプロキシーです。
類似製品としてはJFrog ArtifactoryやSonatype Nexus、Harbor(v2.1.1以降Docker Hubのみ)があります。

Category Direction - Dependency Proxy | GitLab https://about.gitlab.com/direction/package/dependency_proxy/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/2a64aa93-192d-0b02-1181-479493cd2235.png)


## 1-2. Dependency Proxyはなぜ必要？

Docker HubのDockerイメージのdocker pullダウンロードに2020年11月から制限がかかるようになりました。

* 無料ユーザー(匿名)：6時間あたり100回まで
* 無料ユーザー(登録済み)：6時間あたり200回まで
* ProおよびTeamプランユーザー：無制限

GitLab CI/CDでも、DockerHubからDockerイメージをdocker pullすることも多く、制限にかかってしまう可能性もあります。

そうなると、CI/CDにも時間がかかりますし、ネットワークトラフィックが無駄に発生してしまうのもよくありません。

現在は、DockerHubのイメージキャッシュとnpmjs.comが対象です。

# 2. Dependency Proxyをセットアップ

設定方法は、以下に書かれています。
GitLab Dependency Proxy administration | GitLab
https://docs.gitlab.com/ee/administration/packages/dependency_proxy.html

## 2-1. gitlab.rbに設定を追記

/etc/gitlab/gitlab.rbに以下の行を追加します。

```yaml
gitlab_rails['dependency_proxy_enabled'] = true
```

## 2-2. Dependency Proxyが保存するイメージのストレージパスを変更

Dockerイメージが沢山ダウンロードされる可能性があるのでデフォルトの`/var/opt/gitlab/gitlab-rails/shared/dependency_proxy/` ではなくて別の場所にしておきましょう。

今回は、`/var/opt/gitlab-cache/dependency_proxy`にしました。

```yaml
gitlab_rails['dependency_proxy_storage_path'] = "/var/opt/gitlab-cache/dependency_proxy"
```

ownerとPermissionは、所有者がgitでパーミッションが700であれば大丈夫でした。

```bash
# ls -la /var/opt/gitlab-cache/dependency_proxy/
合計 0
drwx------ 2 git  root  6 12月 30 19:34 .
drwxr-xr-x 4 root root 49 12月 30 19:51 ..
```

## 2-3. reconfigureして設定を反映させる

```bash
$ sudo gitlab reconfigure
```

reconfigureした後にGitLabを再起動します。

```bash
$ sudo service gitlab restart
```

# 3. Dependency Proxy(依存関係プロキシ)の動作をグループで確認

Dependency Proxyはグループ単位で利用できます。
`DependencyProxyTestGroup`というグループを作ってみました。
グループの設定でDependency Proxyの画面を見てみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/fcd37c84-7a7e-3055-f55f-8a05ce3bc065.png)

プロキシーURLは以下になります。`https://gitlab.example.jp/dependencyproxytestgroup/dependency_proxy/containers`

```
docker login gitlab.example.jp
```
でloginしてから

```
docker pull gitlab.example.jp:443/dependencyproxytestgroup/dependency_proxy/containers/alpine:latest
```
のようにして利用できるようです。

# 4. まとめ

omnibusインストールしたGitLabであれば設定自体は難しくありません。
また、GitLab.comの無料アカウントでも既に利用できます。GitLab.comのCI/CDの無料アカウントは利用できる時間が400分に制限されてしまっているので、docker pullの時間が短くなれば全体で利用できる回数も増えるでしょう。

次の利用編は、どういう風に使うか確認します。