PowerShellのTab補完をbashのようにする

Windows PowerShell (この記事の執筆時点でバージョンは5.1) でTabキーを押したときの補完方法をbashのようにする方法について調べました。

デフォルトでの補完方法

まず、デフォルトでのWindows PowerShellの補完方法について説明します。例として、20210101.txt, 20210103.txtという2つのファイルがあるディレクトリでWindows PowerShellのシェルを開いている場合を考えます。

Tabによる補完

1つ目の補完はTabを使う方法です。Windows PowerShell2を押したあとにTabを押すと

> .\20210101.txt

と表示され、さらにもう一度Tabを押すと

> .\20210103.txt

が表示されます。これは伝統的なコマンドプロンプトの補完方法と同じです。

Ctrl + Spaceによる補完

2つ目の補完方法はCtrl + Spaceを使う方法です。Windows PowerShell2を押したあとにCtrl + Spaceを押すと、2つのファイル名の共通prefixである2021010の部分までが確定して、かつ、1個目の候補である20210101.txtの残り部分 (1.txt) が選択済である状態になります(言葉で説明しづらいので実際に試してみてください)。

Windows PowerShellの補完方法がどうなっているかを調べるにはGet-PSReadLineKeyHandlerというコマンドレットを使います。デフォルト設定では以下でした。

コンプリート機能
========

Key        Function            Description
---        --------            -----------
Ctrl+Space MenuComplete        入力候補が 1 つだけ存在する場合は、その候補で入力を補完します。それ以外の場合は、入力候
                               補のメニューから項目を選択して入力を補完します。
Tab        TabCompleteNext     次の入力候補を使用して入力を補完します
Shift+Tab  TabCompletePrevious 前の入力候補を使用して入力を補完します

Tabによる補完方法を変える

デフォルトのTabの補完方法は耐え難いものがあるので、Tabbashzshのような補完ができるように変更します。その方法が PowerShellでbash-like, zsh-likeなタブ補完 - Qiita に書いてありました。

bash風の補完

> Set-PSReadLineKeyHandler -Key Tab -Function Complete

zsh風の補完(デフォルトでCtrl+Spaceによりなされる補完と同じ)

> Set-PSReadLineKeyHandler -Key Tab -Function MenuComplete

ただし、この設定はWindows Powershellのウィンドウを閉じると消えてしまいます。恒久的にこの設定を有効にしたければ、プロファイル(.bash_profile的な設定ファイル)を編集する必要があります。プロファイルは何個も種類があって正直よくわかってないですが、私は$PROFILE.CurrentUserAllHosts

Set-PSReadLineKeyHandler -Key Tab -Function Complete

を設定しておきました。

PowerShellからAnaconda Pythonの仮想環境を使えるようにしたときのメモ

PowerShellにてAnaconda Pythonの仮想環境をactivateしようとしてactivate (仮想環境名)というコマンドを実行しても何も起こりません。これを修正しようとしたときにやったことのメモです。注:私はAnaconda PythonにもPowerShellにも精通していないため、これが正しい方法かはわかりません。

condaのバージョンを最新にする

  • conda --versionでバージョンを調べると4.5.11と古かったので、以下の方法で4.9.2にupdate

Windows PowerShell から Anaconda 環境を起動できるようにするための初期化コマンドを実行

> conda init powershell
no change     C:\ProgramData\Anaconda3\Scripts\conda.exe
no change     C:\ProgramData\Anaconda3\Scripts\conda-env.exe
no change     C:\ProgramData\Anaconda3\Scripts\conda-script.py
no change     C:\ProgramData\Anaconda3\Scripts\conda-env-script.py
no change     C:\ProgramData\Anaconda3\condabin\conda.bat
no change     C:\ProgramData\Anaconda3\Library\bin\conda.bat
no change     C:\ProgramData\Anaconda3\condabin\_conda_activate.bat
no change     C:\ProgramData\Anaconda3\condabin\rename_tmp.bat
no change     C:\ProgramData\Anaconda3\condabin\conda_auto_activate.bat
no change     C:\ProgramData\Anaconda3\condabin\conda_hook.bat
no change     C:\ProgramData\Anaconda3\Scripts\activate.bat
no change     C:\ProgramData\Anaconda3\condabin\activate.bat
no change     C:\ProgramData\Anaconda3\condabin\deactivate.bat
modified      C:\ProgramData\Anaconda3\Scripts\activate
modified      C:\ProgramData\Anaconda3\Scripts\deactivate
modified      C:\ProgramData\Anaconda3\etc\profile.d\conda.sh
modified      C:\ProgramData\Anaconda3\etc\fish\conf.d\conda.fish
no change     C:\ProgramData\Anaconda3\shell\condabin\Conda.psm1
modified      C:\ProgramData\Anaconda3\shell\condabin\conda-hook.ps1
no change     C:\ProgramData\Anaconda3\Lib\site-packages\xontrib\conda.xsh
modified      C:\ProgramData\Anaconda3\etc\profile.d\conda.csh
modified      C:\Users\(ユーザ名)\Documents\PowerShell\profile.ps1
modified      C:\Users\(ユーザ名)\Documents\WindowsPowerShell\profile.ps1

==> For changes to take effect, close and re-open your current shell. <==

改変されたprofile.ps1を確認

このコマンドによって改変されたC:\Users\(ユーザ名)\Documents\PowerShell\profile.ps1およびC:\Users\(ユーザ名)\Documents\WindowsPowerShell\profile.ps1を見に行くと、いずれにも以下のコードが付け足されていることを確認しました。(profile.ps1が2つあるのは、たぶんWindows 10に組み込みで入っているWindows PowerShellに加えて、私がPowerShell Coreを別途インストールしてあることが原因です。)

#region conda initialize
# !! Contents within this block are managed by 'conda init' !!
(& "C:\ProgramData\Anaconda3\Scripts\conda.exe" "shell.powershell" "hook") | Out-String | Invoke-Expression
#endregion

スクリプト実行ポリシーを変更

次に、さきほどの指示通り別のWindows PowerShellを起動すると、以下のエラーが出ました。

. : このシステムではスクリプトの実行が無効になっているため、ファイル C:\Users\(ユーザ名)\Documents\WindowsPowerShell\profile.ps1
 を読み込むことができません。詳細については、「about_Execution_Policies」(https://go.microsoft.com/fwlink/?LinkID=13517
0) を参照してください。
発生場所 行:1 文字:3
+ . 'C:\Users\(ユーザ名)\Documents\WindowsPowerShell\profile.ps1'
+   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : セキュリティ エラー: (: ) []、PSSecurityException
    + FullyQualifiedErrorId : UnauthorizedAccess

これは、私のWindows Powershellスクリプト実行ポリシーがRestrictedのままだったことが原因でした。

> Get-ExecutionPolicy
Restricted

そこで、管理者権限付きのWIndows PowerShellを起動して、以下のコマンドを実行し、スクリプト実行ポリシーを変更しました(注:システム全体に影響を与えます)。

> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned

そして、改めてまた別のWIndows PowerShellを起動することで、無事Anaconda Pythonを使えるPowerShell環境ができたようです。conda activateによる環境の変更も実現できています。

Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

新しいクロスプラットフォームの PowerShell をお試しください https://aka.ms/pscore6

パーソナル プロファイルとシステム プロファイルの読み込みにかかった時間は 1083 ミリ秒です。
(base) PS C:\Users\(ユーザ名)> conda activate sandbox
(sandbox) PS C:\Users\(ユーザ名)>

同様に、PowerShell CoreからもAnaconda Pythonが使えることを確認しました。

ただ、profile.ps1のコードが増えた影響か、Windows PowerShellを起動するたび毎回約1秒かかるようになってしまいました。これが嫌な場合、Anaconda がやっと PowerShell に公式対応した - Qiita を真似して、condainiという名前の関数を手動で呼んだときだけAnaconda Pythonが使えるように変更するのがよさそうです(私は未テスト)。以下にコードを引用します。

#region conda initialize
Function condaini{
  (& "c:\Users\user\Anaconda3\Scripts\conda.exe" "shell.powershell" "hook") | Out-String | Invoke-Expression
}
#endregion

参考URLs

Visual Studio Codeのショートカットキー集

普段使わなくて覚えられないものを使いこなせるようになるようメモ書き。Windowsで動作確認しています。Ctrl / Shift / Altのコンビネーションが複雑で覚えるのが大変です…

カーソル移動

  • Ctrl + Enter: カーソルがどこにあっても、カーソルの下に空白行を作ってカーソルを移動
  • Ctrl + Shift + Enter: カーソルがどこにあっても、カーソルの上に空白行を作ってカーソルを移動
  • Ctrl + Shift + \: 対応する括弧にカーソルを移動

範囲選択

  • 行番号の部分をドラッグ: 行単位で選択
  • Ctrl + L: カーソルのある行を選択。繰り返し押すと選択範囲が下に伸びる
  • Alt + Shift + → or ←: 単語やカッコなどの単位で選択範囲を広げる
  • Ctrl + Shift + Alt + ↑ or ↓: 矩形選択
    • 「マウスのホイールでドラッグ」、「Shift + Altを押しながらマウスの左ボタンでドラッグ」でもOK
  • Altを押しながらクリック: マルチカーソル

編集

  • 何も選択していない状態でCtrl + C: カーソルのある行をコピー
  • 何も選択していない状態でCtrl + X: カーソルのある行を切り取り
  • Alt + ↑ or ↓: カーソルのある行 or 選択中の行を1行移動
  • Ctrl + Shift + K: カーソルのある行を削除(Ctrl + Xとは違い、クリップボードに削除された行の情報は入らない)
  • Shift + Alt + ↑ or ↓: カーソルのある行をコピーして、上または下に挿入
  • Alt + ↑ or ↓: カーソルのある行を上または下に移動

表示

  • Ctrl + Shift + [ or ]: カーソルのある行のコードを折りたたんだり戻したり
  • Ctrl + K Ctrl + 0: すべてのコードを折りたたむ
  • Ctrl + K Ctrl + J: すべてのコードの折りたたみを解除する

定義

  • F12: 定義へ移動
  • Alt + ←: 元の場所へ戻る
  • Alt + F12: Peek Definition (定義を小窓で表示)
  • Ctrl + K, F12: 定義を別ウィンドウで並べて表示

リファクタリング

  • F2: カーソル位置の単語をリネーム。プロジェクト内の複数ファイルにまたがって行われる。コメントアウト部は無視されるようだ。
  • Ctrl + F2: カーソル位置の単語を全選択状態にする。コメントアウト部も選択対象となる。
  • Ctrl + Shift + L: 選択部分と同じ文字列を全選択状態にする
  • Shift + Alt + F: ソースコード全体をフォーマット
  • Ctrl + K, Ctrl + F: 選択部分をフォーマット

参考文献

Python 3のsqlite3モジュールでSQLiteの練習

Python 3の標準ライブラリであるsqlite3を使って、SQLite と呼ばれるデータベースを触ってみるメモです。

基本

テーブルを作成

以下のコードでは、都道府県のデータを格納するprefecturesという名前のテーブルを定義します。このテーブルは、name(都道府県名), capital(都道府県庁所在地), population(人口), area(面積)という4つのカラムを持ちます。

import sqlite3

# データベースの保存先
database_store_path = './example.db'

# 最初にデータベースを表す Connection オブジェクトを作る
conn = sqlite3.connect(database_store_path)

# カーソルオブジェクトをつくる
c = conn.cursor()

# executeによりSQLコマンドを実行
# ここでは、'prefectures'という名前のtableを生成するSQLコマンドを実行
# ここでtext, integer, realというのは「カラム型」を意味する
c.execute('''CREATE TABLE prefectures
             (name text, capital text, population integer, area real)''')

データを挿入

次に、prefecturesテーブルにいくつかの都道府県のデータを挿入していきます。以下では、c.execute()を使ってデータを1個ずつ挿入する方法と、c.executemany()を使ってデータ列を一度に挿入する方法を示しています。

人口、面積のデータは英語版Wikipediaを参照しました。

# executeによりSQLコマンドを実行
# ここでは、'stocks'という名前のtableに、1個分のデータを挿入するSQLコマンドを実行
c.execute("INSERT INTO prefectures VALUES ('Kanagawa','Yokohama',9058094,2415.83)")
c.execute("INSERT INTO prefectures VALUES ('Tokyo','Tokyo',13929280,2194.07)")

# '?'というプレースホルダーを使って1個分のデータを挿入することもできる
c.execute("INSERT INTO prefectures VALUES (?,?,?,?)", ('Chiba', 'Chiba', 6278060, 5157.61))

# '?'というプレースホルダーを使って複数のデータを挿入することもできる
prefecture_list = [('Tochigi', 'Utsunomiya', 1943886, 6408.09),
                   ('Ibaraki', 'Mito', 2871199, 6097.19)]
c.executemany("INSERT INTO prefectures VALUES (?,?,?,?)", prefecture_list)

後始末

以下のコードによりDBを更新して保存します。

# 変更を保存 (commit)
conn.commit()

# 後始末
conn.close()

データの読み込み

さきほどexample.dbに保存したテーブルに格納されたデータを読み込んでみます。データの読み込み方は、SQLite入門 によると以下の3種類あります。実際は1番目と2番目を使いそうな気がします。

# 一度保存したDBを開く
conn = sqlite3.connect(database_store_path)
c = conn.cursor()

# 1. カーソルをイテレータ (iterator) として扱う
c.execute('SELECT * FROM prefectures')
for row in c:
    print(row)
print()
 
# 2. fetchallで結果リストを取得する
c.execute('SELECT * FROM prefectures')
for row in c.fetchall():
    print(row)
print()
 
# 3. fetchoneで1件ずつ取得する
c.execute('SELECT * FROM prefectures')
print(c.fetchone())  # 1番目のレコード
print(c.fetchone())  # 2番目のレコード
print(c.fetchone())  # 3番目のレコード
print(c.fetchone())  # 4番目のレコード
print(c.fetchone())  # 5番目のレコード
print(c.fetchone())  # 6番目のレコードは存在しないのでNoneが返る
print()

# 後始末
conn.close()

出力結果は以下のとおりです。

('Kanagawa', 'Yokohama', 9058094, 2415.83)
('Tokyo', 'Tokyo', 13929280, 2194.07)
('Chiba', 'Chiba', 6278060, 5157.61)
('Tochigi', 'Utsunomiya', 1943886, 6408.09)
('Ibaraki', 'Mito', 2871199, 6097.19)

('Kanagawa', 'Yokohama', 9058094, 2415.83)
('Tokyo', 'Tokyo', 13929280, 2194.07)
('Chiba', 'Chiba', 6278060, 5157.61)
('Tochigi', 'Utsunomiya', 1943886, 6408.09)
('Ibaraki', 'Mito', 2871199, 6097.19)

('Kanagawa', 'Yokohama', 9058094, 2415.83)
('Tokyo', 'Tokyo', 13929280, 2194.07)
('Chiba', 'Chiba', 6278060, 5157.61)
('Tochigi', 'Utsunomiya', 1943886, 6408.09)
('Ibaraki', 'Mito', 2871199, 6097.19)
None

応用

特定のカラムだけを取り出す

4つのカラムのうち、面積と人口のカラムのみを取り出すにはSELECTを以下のように使います。

# 一度保存したDBを開く
conn = sqlite3.connect(database_store_path)
c = conn.cursor()

# 特定の列だけを取り出す
c.execute('SELECT area,population FROM prefectures')
for row in c:
    print(row)

# 後始末
conn.close()

結果は以下です。

(2415.83, 9058094)
(2194.07, 13929280)
(5157.61, 6278060)
(6408.09, 1943886)
(6097.19, 2871199)

これ以降、DBを開いてカーソルを取得する部分と後始末の部分は省略します。変数cにはカーソルが入っていると思ってください。

特定の条件にあったデータだけを取り出す

人口が500万以上のデータだけを取り出すにはSELECTWHEREで条件を加えます。

# 人口が500万以上の行だけを取り出す
c.execute('SELECT * FROM prefectures WHERE population > 5000000')
for row in c:
    print(row)

結果は以下です。

('Kanagawa', 'Yokohama', 9058094, 2415.83)
('Tokyo', 'Tokyo', 13929280, 2194.07)
('Chiba', 'Chiba', 6278060, 5157.61)

データを特定の条件で並び替える

例えば人口が多い順にデータを並び替えて取り出すにはSELECTORDER BYで条件を加えます。最後のDESCというのが降順を意味していて、これをASCにするか省略するかすると昇順になります。

# 人口が多い順に取り出す
c.execute('SELECT * FROM prefectures ORDER BY population DESC')
for row in c:
    print(row)

結果は以下です。

('Tokyo', 'Tokyo', 13929280, 2194.07)
('Kanagawa', 'Yokohama', 9058094, 2415.83)
('Chiba', 'Chiba', 6278060, 5157.61)
('Ibaraki', 'Mito', 2871199, 6097.19)
('Tochigi', 'Utsunomiya', 1943886, 6408.09)

カラムを追加する

人口密度を表すカラムを追加してみます。SQL文でデータを追加・更新・削除する方法 (2/2)を参考にしました。

# 人口密度を表すカラムを追加
c.execute('ALTER TABLE prefectures ADD population_density float')
# 人口密度を挿入
c.execute('UPDATE prefectures SET population_density=population / area')

# 結果を表示
c.execute('SELECT * FROM prefectures')
for row in c:
    print(row)

結果は以下です。

('Kanagawa', 'Yokohama', 9058094, 2415.83, 3749.474921662534)
('Tokyo', 'Tokyo', 13929280, 2194.07, 6348.603280661054)
('Chiba', 'Chiba', 6278060, 5157.61, 1217.242094691146)
('Tochigi', 'Utsunomiya', 1943886, 6408.09, 303.3487357387302)
('Ibaraki', 'Mito', 2871199, 6097.19, 470.9052858775928)

素性が不明なデータベースを探索

データベースファイルが与えられたときに中身を探索する方法について記します。ちなみに、db.pyでデータベース探索 にあるように、db.pyというツールを使えばもっとかんたんにできるようですが、ここでは練習としてsqlite3モジュールのみで探索してみます。

まずはデータベースに格納されているテーブル一覧を取得する方法です。sqlite_masterに格納されている情報を使います。

# テーブル一覧を取得
# c.f. https://www.kite.com/python/answers/how-to-list-tables-using-sqlite3-in-python
c.execute("SELECT name FROM sqlite_master WHERE type='table'")
print(c.fetchall())

結果は以下です。

[('prefectures',)]

これでprefecturesという名前のテーブルがあることがわかりました。

次に、prefecturesテーブルのカラム名を取得します。やり方が複数ありそうで自信がありませんが、以下のコードで取得できました。

# テーブルのカラム名を取得
# https://stackoverflow.com/questions/947215/how-to-get-a-list-of-column-names-on-sqlite3-database")
c.execute("SELECT name FROM PRAGMA_TABLE_INFO('prefectures')")
print(c.fetchall())

結果は以下です。

[('name',), ('capital',), ('population',), ('area',), ('population_density',)]

TensorFlow / Kerasにおけるlogitsの意味

TensorFlowやKerasを使うと遭遇する logits という用語、ざっと検索してもすぐに意味が出てこなかったので書いておきます。なお、この用語は複数の意味を持つ単語なので注意願います。この記事ではあくまで TensorFlow / Keras でのlogitsの意味を説明しています。

logitsの定義

scikit-learnとTensorFlowによる実践機械学習 (Amazonアフィリエイトリンク) のp267を引用すると、logitsとは、「ソフトマックス活性化関数に通す前のニューラルネットワークの出力」です。

概念図

画像を3クラスに分類する分類器をニューラルネットで設計したときの典型的な例を以下に示します。ニューラルネットに1枚画像を入力し、  \left[4.0, 2.0, 1.0  \right] ^T という出力を得たとします。これはソフトマックス活性化関数に通す前の値であり、logitsと呼ばれるものです。

f:id:minus9d:20201025192350p:plain

このlogitsを、ソフトマックス活性化関数に与えて得られる出力は、確率を表すベクトルです。ソフトマックス活性化関数の定義に従って計算すると、 \left[0.844, 0.114, 0.042  \right] ^T が得られます。確率なので足すと1.0になっています。0.844の部分の計算はPythonだと以下のようになります。

>>> import math
>>> print(math.exp(4.0) / (math.exp(4.0) + math.exp(2.0) + math.exp(1.0)))
0.8437947344813395

この確率を表すベクトルと、正解ベクトル  \left[1.0, 0.0, 0.0  \right] ^T との間の誤差は、通常、2つの確率分布の距離を計算する関数である交差エントロピー誤差を用いて計算されます。交差エントロピー誤差の定義に従って計算すると、 0.170 になります。この計算はPythonだと以下のようになります。

>>> import math
>>> print((- 1.0 * math.log(0.8437947) - 0.0 * math.log(0.11419519) - 0.0 * mat
h.log(0.04201007)))
0.1698460604208926

tensorflowでの関数

さきほどの図と同じ計算をtensorflowの関数を使って行うと以下のようになります。

import tensorflow as tf


logits = [[4.0, 2.0, 1.0]]
labels = [[1.0, 0.0, 0.0]]

probabilites = tf.nn.softmax(logits)
print(probabilites)  # [[0.8437947  0.11419519 0.04201007]]

cross_entropy_loss = tf.losses.categorical_crossentropy(y_true=labels, y_pred=probabilites)
print(cross_entropy_loss)  # [0.16984598]

softmaxを経由せず、いきなり交差エントロピー誤差を計算する方法もあります。1つ目は、softmax_cross_entropy_with_logits()を使う方法です。

cross_entropy_loss1 = tf.nn.softmax_cross_entropy_with_logits(labels=labels, logits=logits)
print(cross_entropy_loss1)  # [0.16984604]

2つ目は、categorical_crossentropy()の引数from_logitsをTrueにする方法です。

cross_entropy_loss2 = tf.losses.categorical_crossentropy(y_true=labels, y_pred=logits, from_logits=True)
print(cross_entropy_loss2)  # [0.16984604]

logitsと確率を間違えて使ってしまうと正しい値を計算できないので気をつけましょう。

Pythonのexceptionをprint()して何も出ない原因

Python 3にて以下のように例外オブジェクトをprint()するコード

try:
    raise ValueError
except Exception as e:
    print(e)

を実行しても、以下のように何も出力されません。




結論からいうと、上記のコードを以下のように修正すると

try:
    raise ValueError('value error has occured')
except Exception as e:
    print(e)

以下の様に出力されるようになります。

value error has occured

これはなぜかを説明していきます。

Pythonのraise文で投げることができるのは、例外クラスか、例外インスタンスのどちらかです( 参考 )。先程の例外クラスを投げた例

    raise ValueError

は、以下

    raise ValueError()

のように、引数無しで生成した例外インスタンスを投げたのと同じになります。

例外インスタンスをつくるときの引数には何を与えればよいでしょうか? 参考

raise Exception('spam', 'eggs')

という例がある通り、引数には任意のオブジェクトを任意の個数与えることができるようです。ただ、普通は、例外が起こった原因を究明するために役立つ情報を文字列で与えることが多いと思います。

ここで設定したオブジェクトは、except節で'as'を使って指定した変数の.argsの中に入っています。また、この変数を文字列として扱うと、.args を参照しなくても引数を直接印字できるようになっています。よって、下の例ではprint(e.args)としてもprint(e)としても同じ結果になります。

try:
    raise ValueError('spam', 'eggs')
except Exception as e:
    print(e.args)  # ('spam', 'eggs') と表示される
    print(e)  # ('spam', 'eggs') と表示される

ここまでの説明により、

try:
    raise ValueError
except Exception as e:
    print(e)

で何も表示されなかった理由がわかりました。

Visual Studio Codeの基本設定

共有設定を使う場合

2020年3月頃からプレビュー機能として提供されている、設定を共有する機能を有効にすることで、複数のマシンでVSCodeの設定を共有できます。参考: 「Visual Studio Code」が設定の同期に対応、Insider版でテスト中 - 窓の杜

  • 左下の歯車をクリック
  • Turn on Setting Sync...をクリック
  • Turn Onをクリック
  • 共有したいものを選んで Sign in & onをクリック
  • Microsoft / GItHub の好きな方でログイン

一から設定する場合

共有設定を使えず一から設定をやり直す必要があるときは、以下を順番に設定。

Settingsを設定

Visual Studio本体の設定はSettingsから行います。File -> Preferences -> Settingsからも開けるけど、Ctrl + , が便利。

拡張機能

まだまだ研究中です。

Snnipetを設定

競技プログラミングで役立ちます(まだほとんど何も登録してませんが)。File -> Preferences -> User Snippetsから好きな言語を選び、例えば以下のようなjsonを作成します。

{
    "is_prime": {
        "prefix": "is_prime",
        "body": [
            "bool is_prime(const ll n){",
            "    if (n <= 1){",
            "         return false;",
            "    }",
            "   for(ll i = 2; i*i <= n; ++i){",
            "       if (n % i == 0){",
            "           return false;",
            "       }",
            "   }",
            "   return true;",
            "}",
        ],
        "description": "judge n is prime or not"
    }
}
エディタで`is_prime`と打ってTabを押せば上記のスニペットを挿入できます。

## 参考文献

* [https://github.com/microsoft/vscode-tips-and-tricks:title]
    * 設定だけでなくショートカットキーの一覧が豊富
* [Visual Studio Code実践ガイド —— 最新コードエディタを使い倒すテクニック (Amazonのアフィリエイトリンク)](https://amzn.to/2JU8M36)