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)

VS CodeでPython 3の競プロコードをデバッグ実行

AtCoderCodeforcesなどの競技プログラミングサイトでは、通常、標準入力から入力を受け取ります。例えばPythonで回答する場合、あなたの回答(例としてsolve.pyとします)は、入力が書かれたテキストファイルinput.txt

$ python solve.py < input.txt

のように与えられたとき、正しく出力することが求められます。

Visual Studio Codeでは<を使った入力や出力はdebugger/runtime specificということになっています (https://code.visualstudio.com/docs/editor/debugging#_redirect-inputoutput-tofrom-the-debug-target) 。私の理解が正しければ、Pythonを実行する処理系が<をうまく扱えない場合、Visual Studio Code<を使う諦めざるを得ないはずです。実際、Windows + Anaconda Pythonという組み合わせで試行錯誤しましたが、うまくいきませんでした。

このように<を使った入力や出力がうまくいかない処理系を使っている場合であっても、Visual Studio CodePythonデバッグができるような方法を考えました。

手順1. Pythonスクリプトに3行追加

Visual Studio Codeは、以下の形式であれば問題なく引数を受け取ってデバッグ可能です。

$ python solve.py input.txt

そこで、以下のどちらでも同じように入力を受け取れるようにPythonスクリプトを変更します。

$ python solve.py < input.txt
$ python solve.py input.txt

そのためには、Pythonスクリプトに以下の行を入れればOKです(参考: how to take a file as input stream in Python - Stack Overflow )。

import sys


if len(sys.argv) == 2:
    sys.stdin = open(sys.argv[1])

例えば ABC146のB問題ですと、回答は以下のようになります。

import sys


if len(sys.argv) == 2:
    sys.stdin = open(sys.argv[1])

N = int(input())
S = input()
T = ""
for ch in S:
    T += chr(ord('A') + (ord(ch) - ord('A') + N) % 26)
print(T)

手順2. Visual Studio Codeデバッグ実行

事前にPython拡張機能を入れて置く必要があります(多分Pythonで検索して最初に出てくるMicrosoftのものでOK)。

  • Pythonコードを右クリックしてVisual Studio Codeで開きます。

  • 左の方にあるデバッグのアイコンをクリックします。Ctrl + Shift + DでもOKです。

f:id:minus9d:20200723181922p:plain

  • "create a launch.json file." をクリックします。

f:id:minus9d:20200723182544p:plain

  • "Python"を選択します。

f:id:minus9d:20200723182626p:plain

  • "Python File"を選択します。

f:id:minus9d:20200723182700p:plain

  • 自動で作成される雛形に、"args": [/path/to/入力ファイルへのパス] を追加します。パスは、あなたのPythonスクリプトのあるディレクトリを基準とした相対パスでもよいようです。以下に例を示します。
{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: Current File",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            "console": "integratedTerminal",
            "args": ["test/sample-1.in"]
        }
    ]
}
  • Pythonスクリプトのタブを選択して、行番号の左側をクリックしてBreakpointをはります。

f:id:minus9d:20200723183947p:plain

  • さっき作った設定が選ばれていることを確認して、再生ボタンを押します。

f:id:minus9d:20200723183414p:plain

  • Debugしましょう!

f:id:minus9d:20200723183548p:plain