printと入力値|Pythonの最初の1行

このページはプロモーション(広告)を含みます。

Pythonの最初の1行(初級・読む25分+演習35分)

この授業のゴール

仕事でどう使うか

コードの結果は、人間が読める形で出して初めて、仕事に使えます。また、人が入力した値、ファイルから読んだ値は、間違い・空欄・全角文字・カンマを含み得ます。入力をそのまま信じて計算すると、誤った金額がそのまま出ます。

路線 この授業の使いどころ
DS(データサイエンティスト) 分析の途中で print により値・型・件数を確認する(デバッグ)。レポートに載せる数値を、桁区切りと小数桁数をそろえて表示する
ML(機械学習エンジニア) 学習のログ(損失、正解率)を読みやすく出す。外部から受け取った設定値の型を検証してから、モデルに渡す
DX(DX推進・AI企画) 現場の入力フォームで、どんな入力を「受け付けない」と決めるかを要件にする。エラーメッセージを、現場の人がわかる日本語にする
RS(研究者) 実験ログに、条件と結果を再現できる形で出力する。測定値の入力ミス(桁違い、単位違い)を検出する

また、print の出力に、パスワード・個人情報・社外秘のデータを出さない、という習慣も、この授業で身に付けます。

前提

次の内容を使います。

この授業のコードも、すべて画面内で実行できます。ただし、キーボード入力を待つ input() は、この教材の実行画面では使えないことがあるので、入力された値を変数に入れて模擬します。

身近な状況:注文確認のメッセージと、入力された価格

注文の確認メッセージを、次の形で出したいとします。

りんごを3個、合計 1,080 円です(税込・割引率 10.0%)

数値を文字に埋め込むとき、次のような書き方をしがちです。

name = 'りんご'
qty = 3
total = 1080
code = "print(name + 'を' + qty + '個、合計' + total + '円です')\n"
try:
    exec(compile(code, 'sample.py', 'exec'), {'name': name, 'qty': qty, 'total': total})
except Exception as e:
    print(type(e).__name__, ':', e)

出力は TypeError : can only concatenate str (not "int") to str です。文字列に整数は足せません。str(qty) で変換して連結する方法もありますが、数が多いと読みにくくなります。この問題を解決するのが f文字列です。

もう1つの状況は、人が入力した価格です。「1,980」「 1980 」「千円」「abc」「空欄」のうち、どれを受け付けて、どれを断るか。仕様を決めてコードにするのが、仕事の中で求められる作業です。

直感的な説明:出力は「見せる形」、入力は「文字の入口」

出力は、計算結果を人に見せるための表示用の形です。1080 という数を 1,080 と表示しても、数そのものは変わりません。表示用に整えた文字列は、計算には使えません。

入力は逆に、外の世界から来る文字の入口です。キーボードから打たれた値は、本人が数のつもりで 1980 と打っても、Pythonから見れば「1, 9, 8, 0 という4文字」です。必ず文字列として届き、そのままでは数の計算ができません。

そこで、入力の処理は次の3段階で考えます。

  1. 整える:前後の空白を除き、カンマなどを取り除く。
  2. 変換する:int() や float() で数にする。変換できなければ「入力不正」。
  3. 検証する:意味のある範囲か(0以上か、上限以内か)を確かめる。

この3段階を通ったものだけを、計算に使います。

正確な定義:print・f文字列・input・try/except

print:print(値1, 値2, ..., sep=' ', end='\n') は、渡された値を文字にして、sep(区切り)でつなぎ、最後に end(終端)を付けて出力します。戻り値は None で、値は返しません。

print('りんご', 3, 1080)
print('りんご', 3, 1080, sep=' / ')
print('A', end='')
print('B')

出力は りんご 3 1080、りんご / 3 / 1080、AB です。複数の値を並べると、型が違ってもエラーにならず、半角空白でつながります。

f文字列:文字列の前に f を付け、{ } の中に式を書くと、その値が埋め込まれます。{式:書式} の形で、見た目を指定できます。

書式 例 結果 意味
{x} f'{1080}' 1080 そのまま
{x:,} f'{1080000:,}' 1,080,000 3桁区切り
{x:.2f} f'{3.14159:.2f}' 3.14 小数点以下2桁
{x:.1%} f'{0.15:.1%}' 15.0% 割合をパーセント表示(100倍して%を付ける)
{x=} f'{x=}' x=1980 変数名と値を表示(確認用)

repr:repr(x) は、プログラムとして書いたときの形の文字列を返します。文字列は引用符付き、改行は \n と表示されるので、'1000' と 1000 を見分けるのに役立ちます。print(repr('1000')) は '1000'、print(repr(1000)) は 1000 です。

input:input('メッセージ') は、画面にメッセージを出し、利用者が打った1行を文字列で返します。改行は含まれません。数を打っても int にはなりません。

raw = input('価格を入力してください: ')   # 1980 と打つと raw は '1980'(str)

try / except:try: の中を実行し、指定した種類の例外(エラー)が起きたら、except 種類: の中を実行します。例外が起きなければ except は実行されません。

try:
    price = int(text)
except ValueError:
    price = None

ValueError は「型は合っているが、値が変換できない」という例外です。例外の詳細は 「例外と後処理」(有料版) で学びます。

段階付き例題:入力の文字列を整えて、検証して、メッセージを出す

問題:入力された文字列から価格を取り出し、0以上の整数なら税込(10%、切り捨て)のメッセージを出す。そうでなければ、理由を出す。

ステップ1:1つの入力で手順を確かめる。

raw = ' 1,980 '
text = raw.strip().replace(',', '')
print(repr(raw))
print(repr(text))

price = int(text)
with_tax = price * 110 // 100
print(f'価格 {price:,} 円 → 税込 {with_tax:,} 円')
print(f'{price=}, {type(price).__name__}')

出力は ' 1,980 '、'1980'、価格 1,980 円 → 税込 2,178 円、price=1980, int です。1980 × 110 ÷ 100 = 2178 ちょうどで、端数はありません。

ステップ2:不正な入力も扱えるようにする。ここでは、複数の入力に同じ処理をするため、for raw in [...]: という繰り返しを使います(「forとrange」(有料版) で学びます。いまは「リストの値を1つずつ raw に入れて、下の字下げした部分を実行する」と読んでください)。

inputs = [' 1,980 ', '12.5', 'abc', '', '-50']
for raw in inputs:
    text = raw.strip().replace(',', '')
    try:
        price = int(text)
    except ValueError:
        print(f'{raw!r}: 整数で入力してください')
        continue
    if price < 0:
        print(f'{raw!r}: 0以上で入力してください')
    else:
        print(f'{raw!r}: OK 価格={price:,}円')

continue は「この回の残りを飛ばして、次の値に進む」という意味、if は条件に合うときだけ実行する文で、どちらも 「ifと条件式」(有料版) 以降で詳しく学びます。{raw!r} は repr で表示する指定です。

ステップ3:出力を読む。

入力 結果 理由
' 1,980 ' OK 価格=1,980円 空白とカンマを除いて整数になる
'12.5' 整数で入力してください int('12.5') は ValueError
'abc' 整数で入力してください 数字でない
'' 整数で入力してください 空文字は変換できない
'-50' 0以上で入力してください 整数だが、価格として不正

ステップ4:設計上の判断を言葉にする。「型として変換できるか」(ValueError)と、「意味として許される値か」(0以上)は別の検証です。-50 は整数に変換できるので、ValueError では検出できません。両方を検査するのが、入力処理の基本です。

操作して理解する:表示を変えて、値は変わらないことを確かめる

次のコードを実行する前に、4つの出力を予想してください。

rate = 0.1234
total = 1234567.891

print(f'{rate:.1%}', f'{rate:.2f}', f'{rate}')
print(f'{total:,.1f}', f'{total:,.0f}', total)
print(f'{total:,.0f}' == '1,234,568', type(f'{total:,.0f}').__name__)
print(f'|{"りんご":<6}|{3:>4}|{1080:>8,}|')

答えと理由:

  1. 12.3% 0.12 0.1234:.1% は100倍して小数1桁で%を付けます。書式を付けなければ、値がそのまま出ます。
  2. 1,234,567.9 1,234,568 1234567.891:表示は丸められますが、total 自体は 1234567.891 のままです。書式指定は、表示だけを変えます。
  3. True str:整形した結果は文字列です。数の計算には使えません。
  4. |りんご | 3| 1,080|:< は左寄せ、> は右寄せ、数字は幅を指定します。表を揃えて出すのに便利です。

自分で rate = 0.5 や total = 999 に替えて試してください。表示用の文字列を変数に取っておいて、後で計算に使うことは避けます。計算は常に元の数で行い、表示の直前に f文字列で整えます。

発展:標準入力・ログ・機密情報

標準入力と標準出力:input() は、プログラムが起動した端末からの入力を読み、print は端末へ出力します。この入出力の窓口を、標準入力・標準出力と言います。コマンドで python script.py < data.txt と書くと、キーボードの代わりにファイルから入力を渡せます。業務の自動化では、人が打つ input() より、ファイルや引数から受け取る方が多くなります(「CSVとJSON」(有料版))。

print と logging:デバッグの途中の print は、確認が済んだら消します。長く動かすプログラムでは、logging(時刻と重要度つきで記録する標準ライブラリ)を使い、出力の種類(情報・警告・エラー)を分けます。

機密情報を出さない:パスワード、APIキー(外部サービスを使うための鍵)、顧客の氏名・住所・電話番号などは、print やログに出すと、画面共有・ログファイル・チャットへの貼り付けから漏れます。デバッグで値を見たいときは、件数・桁数・先頭の数文字だけを出す、一部を *** で隠す、などの工夫をします。社内規程や個人情報の取り扱い規則は、最新のものを確認してください。

入力検証は「受け付けない」ための設計:Webアプリでは、利用者が悪意で作った入力(極端に長い文字列、特殊な記号)が来ることも想定します。型の変換、長さ、範囲、許可する文字を限定する検証は、セキュリティの基本です。ここでの int() の変換と範囲の検査は、その最初の一歩です。

よくある失敗

失敗1:文字列に数をそのまま足して表示しようとする

誤り:メッセージの途中に、数を + でつなぐ。

total = 1080
code = "print('合計: ' + total + '円')\n"
try:
    exec(compile(code, 'sample.py', 'exec'), {'total': total})
except Exception as e:
    print(type(e).__name__)

print('合計: ' + str(total) + '円')
print(f'合計: {total:,}円')
print('合計:', total, '円')

出力は TypeError、合計: 1080円、合計: 1,080円、合計: 1080 円 です。print に値をコンマで並べる方法は、自動で空白が入るので、円 の前に空白が入ります。

直し方:f文字列を基本にする。str() で変換して + でつなぐ方法も使えますが、数が多いと式が読みにくくなります。

失敗2:入力された文字列を、変換せずに計算に使う

誤り:input() の戻り値(文字列)を、そのまま数として扱う。ここでは、入力された値を raw = '1980' で模擬します。

raw = '1980'

print(raw * 2)

code = 'print(raw > 1000)\n'
try:
    exec(compile(code, 'sample.py', 'exec'), {'raw': raw})
except Exception as e:
    print(type(e).__name__, ':', e)

print(int(raw) * 2, int(raw) > 1000)

出力は 19801980、TypeError : '>' not supported between instances of 'str' and 'int'、3960 True です。raw * 2 はエラーなしで文字の繰り返しになります。比較の > は文字と数では TypeError になります。

直し方:入力は受け取った直後に、整える・変換する・検証する。以降の計算には、変換後の変数だけを使います。変数名で raw_price(入力そのまま)と price(変換後)を区別すると、取り違えを防げます。

失敗3:printの結果を変数に入れて、後で計算に使う

誤り:print(...) が値を返すと考える。

result = print('税込価格:', 1980 * 110 // 100)
print(result)
print(type(result).__name__)

code = 'print(result * 2)\n'
try:
    exec(compile(code, 'sample.py', 'exec'), {'result': result})
except Exception as e:
    print(type(e).__name__, ':', e)

出力は 税込価格: 2178、None、NoneType、TypeError : unsupported operand type(s) for *: 'NoneType' and 'int' です。print は画面に出すだけで、値は何も返しません(None)。計算結果は先に変数へ入れ、その変数を print します。

直し方:with_tax = 1980 * 110 // 100 と先に代入し、print(with_tax) で表示する。「表示」と「値の保持」は別の操作です。

失敗4:表示用に整えた文字列を、計算に使う

誤り:3桁区切りにした値を変数に取っておき、あとで足し算に使う。

total = 1234567
total_text = f'{total:,}'
print(total_text, type(total_text).__name__)

code = 'print(total_text + 1)\n'
try:
    exec(compile(code, 'sample.py', 'exec'), {'total_text': total_text})
except Exception as e:
    print(type(e).__name__)

try:
    print(int(total_text))
except ValueError:
    print('ValueError: カンマ付きは int() に渡せません')
print(total + 1)

出力は 1,234,567 str、TypeError、ValueError: カンマ付きは int() に渡せません、1234568 です。整形した結果は文字列で、数ではありません。さらに、カンマ付きのままでは int() でも戻せません。

直し方:数の変数 total を計算用に残し、表示の瞬間だけ f'{total:,}' を使う。total_text のような表示用の変数は、表示以外には使いません。

まとめ

用語

f文字列(f-string)

f'...{式:書式}...' の形で、式の値を文字列に埋め込む書き方。

標準入力(standard input)

プログラムが外から文字を受け取る窓口。input() はここから1行読む。

例外(exception)

実行中に起きたエラーを表す仕組み。try / except で捕まえて処理できる。

入力検証(input validation)

入力が、型・範囲・形式の条件を満たすかを確かめ、満たさない入力を受け付けないこと。

よくある質問

f文字列と `str()` での連結は、どちらを使うべきですか?

基本はf文字列です。数や変数が増えても読みやすく、:, や .2f で書式も指定できます。str() で連結する方法は、短い場合や古い書き方を読むときに知っておけば十分です。

`print` に値をコンマで並べるのと、f文字列は何が違いますか?

コンマで並べると、半角空白が自動で入ります。f文字列では、空白や記号の位置を自分で決められ、書式も指定できます。ログの確認ならコンマ並び、報告用のメッセージならf文字列、と使い分けます。

`input()` が使えない環境では、どうやって練習しますか?

この教材のように、入力された値を raw = '1980' のように変数へ入れて模擬します。入力が文字列で届く点は同じです。実際のWebアプリや業務システムでは、フォームやファイルから届く文字列を、同じ手順で整えて変換します。

変換できない入力は、エラーとして止めるべきですか?

場面によります。画面の入力なら、メッセージを出してやり直してもらいます。ファイルの一括処理なら、不正な行を記録して処理を続け、最後に件数を報告する設計が多いです。どちらにするかは要件で決め、黙って捨てない点が共通のルールです。

全角の数字 `'123'` は `int()` で変換できますか?

Pythonの int() は全角数字も変換できます(結果は 123)。ただし、データの取り込みでは全角が混ざること自体が品質の問題なので、変換できたことに安心せず、入力ルールとして半角に統一するかを決めます。全角カンマ , は , とは別の文字で、replace(',', '') では除かれません。

デバッグで `print` した値を、そのまま報告書に載せてよいですか?

載せる前に、元データの値と一致するか、単位と丸め方が仕様どおりかを確認します。print の表示は丸めや書式の影響を受けています。報告する数値は、計算用の元の値から、報告用の書式で出し直します。

確認問題

問1 利用者が 1980 とキーボードで入力した。raw = input('価格: ') で得られる raw の型はどれか。

  1. ① str(文字列)
  2. ② int(整数)
  3. ③ float(小数)
  4. ④ 利用者が数を打てば自動的に int になる
解答と解説

正解:①

input() は入力された1行を常に文字列で返します。数として使うには int() で変換し、変換できない場合のことも考える必要があります。

問2 print('A', 'B', 'C', sep='-') の出力はどれか。

  1. ① A-B-C-
  2. ② A-B-C
  3. ③ A B C
  4. ④ ABC
解答と解説

正解:②

sep は、値と値の間に入れる区切りです。指定しなければ半角空白です。

問3 f'{1234567:,}' の結果はどれか。

  1. ① '1.234567'
  2. ② '1,234,567.0'
  3. ③ '1,234,567'(文字列)
  4. ④ 1234567(整数)
解答と解説

正解:③

:, は3桁区切りの指定です。f文字列の結果は文字列で、整数ではありません。計算に使う値は元の数に残します。

問4 x = print('こんにちは') を実行した後の x の値はどれか。

  1. ① 'こんにちは'
  2. ② 0
  3. ③ True
  4. ④ None
解答と解説

正解:④

print は画面に出力するだけで、戻り値は None です。表示と値の保持は別の操作です。

問5 f'{0.15:.1%}' の結果はどれか。

  1. ① '15.0%'
  2. ② '0.2%'
  3. ③ '0.15%'
  4. ④ '1.5%'
解答と解説

正解:①

% の書式は、値を100倍してから、小数点以下の桁数を指定して % を付けます。0.15 は割合なので 15.0% と表示されます。

問6 try: price = int(text) except ValueError: pass(何もしない)と書いた。この書き方の問題として最も適切なものはどれか。

  1. ① 変換に成功した場合も except が実行される
  2. ② 変換に失敗しても何も知らせず、price が前の値のまま、または未定義のまま後続の処理に進み、誤った結果や別のエラーを招く
  3. ③ ValueError はこの方法では捕まえられない
  4. ④ pass は文法エラーになる
解答と解説

正解:②

except の中で何もしないと、失敗が見えなくなります。入力不正として扱う(メッセージ、None、件数の記録など)処理を必ず書きます。

次に学ぶこと

次は エラーを読んで直す で、エラーメッセージの読み方(エラーの種類・行番号・原因)と、直し方の手順を学びます。この授業の TypeError と ValueError も、そこで整理します。

この授業の確認問題だけでモジュールの習得とはしません。PY01 の総合テストと自力課題で判定します。ファイルから値を読み込む方法は 「CSVとJSON」(有料版) と 「ファイルの読み書き」(有料版) で扱います。

キャリア学習:データサイエンティスト・機械学習エンジニア・DX推進・研究者を目指す人の学習アプリ。164モジュール・984授業を、ブラウザで動くSQLとPythonの演習で。基礎と各分野の最初のモジュールは無料。全部は2,980円の買い切り。

アプリを無料で開く有料版と無料版の違い