「このアルミ板、重さはどれくらいだろう?」「DIYで使う鉄パイプの重量を知りたいけど、体積と密度から計算するのは面倒…」「仕事で材料の見積もりをする時、手早く重量を計算できるツールがあったらいいのに!」
こんにちは!samurai-human-goです。
日常業務やDIY、趣味のプロジェクトなどで、金属や木材といった材料の「重さ」を手早く知りたくなる場面は意外と多いですよね。体積は分かるけど、いちいち密度を調べて電卓を叩くのは少し手間がかかります。
今回は、そんな悩みを解決する超実用的なプロジェクトとして、様々な単位表記に対応した「材料重量計算スクリプト」をPythonでゼロから作り上げていきます! このツールを使えば、15000mm3
や2.5cm^3
といった体積を入力するだけで、アルミ、鉄、ステンレスの重量を一瞬で計算できます。さらに、単位なしで100
と入力された場合でも、複数の可能性を提示してくれる賢い機能も搭載します。
このプロジェクトを通して、辞書の効果的な使い方、正規表現(re
)による柔軟な入力解析、そしてプログラムを構造化するための関数設計など、Pythonにおける多くの重要なテクニックを実践的に学んでいきましょう!
1. このツールで何ができる?(プロジェクト概要)
今回作成する「材料重量計算スクリプト」は、コンソール上で動作するシンプルなツールですが、以下のような便利な機能を持っています。
- 材料選択機能: スクリプト起動時に、アルミ、鉄、ステンレスの中から計算したい材料を選択できます。
- 柔軟な体積入力:
11520mm^3
,24050㎣
,1.5m^3
,立方センチメートル
,cm3
といった、様々な単位表記や書き方を自動で認識します。 - 単位なし入力への対応:
100
のように数値のみが入力された場合、それが100㎣
,100㎤
,100㎥
だった場合の3パターンの重量をそれぞれ計算して提示します。 - 見やすい重量表示: 計算結果の重量を、その重さに応じて自動的に「g(グラム)」「kg(キログラム)」「t(トン)」を使い分けて分かりやすく表示します。
2. プロジェクトの全体像(完成コード)
まずは、今回作成するスクリプトの全体像を見てみましょう。
import re
# --- 1. 基本設定(定数) ---
# 各材料の密度 (g/cm^3)
# 一般的な値を採用しています。
DENSITIES = {
'アルミ': 2.70,
'鉄': 7.87,
'ステンレス': 7.93, # SUS304を想定
}
# 単位をcm^3に変換するための換算係数
# 様々な単位表記をここで吸収します
UNIT_TO_CM3_FACTORS = {
# 立方ミリメートル系 (1 cm^3 = 1000 mm^3)
'mm^3': 0.001, 'mm3': 0.001, '㎣': 0.001, '立方ミリメートル': 0.001,
# 立方センチメートル系
'cm^3': 1, 'cm3': 1, '㎤': 1, '立方センチメートル': 1,
# 立方メートル系 (1 m^3 = 1,000,000 cm^3)
'm^3': 1_000_000, 'm3': 1_000_000, '㎥': 1_000_000, '立方メートル': 1_000_000,
}
# --- 2. ヘルパー関数 ---
def format_weight(weight_g):
"""重量(g)をg, kg, tの適切な単位に変換してフォーマットする関数"""
try:
weight_g = float(weight_g)
if weight_g >= 1_000_000:
# 1,000,000g (1t) 以上はトンで表示
return f"{weight_g / 1_000_000:.3f} t"
elif weight_g >= 1000:
# 1,000g (1kg) 以上はキログラムで表示
return f"{weight_g / 1000:.3f} kg"
else:
# それ以外はグラムで表示
return f"{weight_g:.3f} g"
except (ValueError, TypeError):
return "計算エラー"
def calculate_and_display(volume_cm3, material_name, original_input_str=""):
"""体積(cm^3)と材料名から重量を計算して表示する関数"""
density = DENSITIES[material_name]
weight_g = volume_cm3 * density
# 単位付きの入力か、数値のみの入力かで表示を少し変える
if original_input_str:
print(f" ▶ [{material_name}] の場合: {format_weight(weight_g)} ({original_input_str})")
else:
print(f" ▶ [{material_name}] の場合: {format_weight(weight_g)}")
# --- 3. メイン処理 ---
def main():
"""メインの実行ループ"""
print("--- 材料重量計算スクリプト ---")
# 材料の選択肢を表示
materials = list(DENSITIES.keys())
print("\nまず、計算したい材料を選択してください。")
for i, name in enumerate(materials):
print(f" {i+1}: {name}")
material_choice = 0
while material_choice not in range(1, len(materials) + 1):
try:
choice_str = input(f"\n番号を入力してください (1-{len(materials)}): ")
material_choice = int(choice_str)
except ValueError:
print("エラー: 番号で入力してください。")
continue
selected_material = materials[material_choice - 1]
print(f"\n--- {selected_material} の重量を計算します ---")
while True:
print("-" * 30)
user_input = input("体積を入力してください (例: 1500mm3, 2.5cm^3)\n(終了する場合は 'q', 材料を変更する場合は 'c' と入力): ")
if user_input.lower() == 'q':
print("スクリプトを終了します。ありがとうございました。")
break
if user_input.lower() == 'c':
main() # main関数を再帰的に呼び出して材料選択からやり直す
break
# 正規表現で数値と単位を抽出
# \s* は0個以上の空白文字にマッチ
pattern = f"([0-9\.\,]+)\\s*({'|'.join(UNIT_TO_CM3_FACTORS.keys())})"
match = re.search(pattern, user_input.replace(',', ''), re.IGNORECASE)
if match:
# 単位が見つかった場合
value_str, unit_str = match.groups()
value = float(value_str)
volume_cm3 = value * UNIT_TO_CM3_FACTORS[unit_str.lower()]
print("\n計算結果:")
calculate_and_display(volume_cm3, selected_material)
else:
# 単位が見つからなかった場合(数値のみかチェック)
try:
value = float(user_input.replace(',', ''))
print(f"\n数値 '{value}' のみが入力されました。各単位での計算結果を表示します。")
# mm^3 の場合
volume_mm3 = value * UNIT_TO_CM3_FACTORS['mm^3']
calculate_and_display(volume_mm3, selected_material, original_input_str=f"{value} ㎣")
# cm^3 の場合
volume_cm3 = value * UNIT_TO_CM3_FACTORS['cm^3']
calculate_and_display(volume_cm3, selected_material, original_input_str=f"{value} ㎤")
# m^3 の場合
volume_m3 = value * UNIT_TO_CM3_FACTORS['m^3']
calculate_and_display(volume_m3, selected_material, original_input_str=f"{value} ㎥")
except ValueError:
print(f"エラー: '{user_input}' は有効な体積として認識できませんでした。")
if __name__ == '__main__':
main()
material_weight_calculator.py
のようなファイル名で保存してください。各部分の詳しい解説はこの後でじっくり行いますので、まずは全体の流れを掴んでください。
3. コードの仕組みを徹底解説!
このスクリプトは、大きく分けて「基本設定」「ヘルパー関数」「メイン処理」の3つの部分から構成されています。それぞれの役割を見ていきましょう。
3.1. 設計の基礎:定数と辞書の準備
スクリプトの冒頭で、計算に必要な基本情報を定数としてまとめています。
<span class="hljs-comment"># 各材料の密度 (g/cm^3)</span>
DENSITIES = { ... }
<span class="hljs-comment"># 単位をcm^3に変換するための換算係数</span>
UNIT_TO_CM3_FACTORS = { ... }
このように、プログラム中で変わらない値や設定を、辞書や変数として冒頭にまとめておくことで、後から材料を追加したり(DENSITIES
に追加)、新しい単位表記に対応したり(UNIT_TO_CM3_FACTORS
に追加)するのが非常に簡単になります。これは、保守性の高いコードを書くための重要なテクニックです。
3.2. ヘルパー関数:処理を部品化する
特定の役割を持つ処理を関数として切り出す(部品化する)ことで、コード全体の見通しが良くなります。
format_weight(weight_g)
: この関数は、グラム(g)単位で渡された重量を、その大きさによってg
,kg
,t
(トン)のいずれかに自動で変換し、見やすい文字列として返します。if/elif/else
文を使った条件分岐の良い例ですね。calculate_and_display(...)
: この関数は、体積(cm³)と材料名から重量を計算し、整形して表示するまでの一連の処理を担当します。計算ロジック(体積 × 密度
)と表示ロジックを一つにまとめています。
3.3. メイン処理 (main()関数):全体の流れを制御
この関数がプログラムの本体です。大きく分けて「材料選択ループ」と「体積入力・計算ループ」の2つのwhile
ループで構成されています。
・入力解析の心臓部:正規表現の活用
このスクリプトで最もテクニカルな部分が、ユーザーの多様な入力を解析する以下の部分です。
pattern = f<span class="hljs-string">"([0-9\.\,]+)\\s*({'|'.join(UNIT_TO_CM3_FACTORS.keys())})"</span>
match = re.search(pattern, user_input.replace(<span class="hljs-string">','</span>, <span class="hljs-string">''</span>), re.IGNORECASE)
これは正規表現(re
モジュール)を使ったパターンマッチングです。
'|'.join(UNIT_TO_CM3_FACTORS.keys())
: まず、単位変換辞書の全てのキー(’mm^3′, ‘mm3’, ‘㎣’…)を|
(ORを意味する)で連結し、(mm^3|mm3|㎣|...)
のような巨大なパターン文字列を動的に生成しています。([0-9\.\,]+)
: 数字、ドット、カンマが1回以上続く部分(つまり数値部分)にマッチします。\\s*
: 数値と単位の間にあるかもしれない0個以上の空白文字にマッチします。re.search(...)
: この組み立てられたパターンでユーザー入力を検索し、マッチすればその結果(数値部分と単位部分)を取得します。
このおかげで、「1,500 mm^3」
のような入力も柔軟に解釈できるのです。
・単位なし入力への対応
正規表現にマッチしなかった場合、プログラムは次に入力が数値のみである可能性を試みます。try-except
ブロックを使ってfloat()
での変換を試み、成功すれば「mm³, cm³, m³だった場合」の3パターンの計算結果をそれぞれ表示します。これにより、ユーザーが単位を付け忘れても、親切な応答を返すことができます。
4. スクリプトの使い方
- 上記のコード全体を
material_weight_calculator.py
として保存します。 - ターミナルやコマンドプロンプトを開き、以下のコマンドでスクリプトを実行します。
python material_weight_calculator.py
- 最初に材料を選択するように求められます。番号で入力してください。
- 次に、体積を入力するように求められます。様々な形式で入力して、正しく計算されるか試してみてください!
実行例:
--- 材料重量計算スクリプト ---
まず、計算したい材料を選択してください。
1: アルミ
2: 鉄
3: ステンレス
番号を入力してください (1-3): 2
--- 鉄 の重量を計算します ---
------------------------------
体積を入力してください (例: 1500mm3, 2.5cm^3)
(終了する場合は 'q', 材料を変更する場合は 'c' と入力): 100cm3
計算結果:
▶ [鉄] の場合: 0.787 kg
------------------------------
体積を入力してください (例: 1500mm3, 2.5cm^3)
(終了する場合は 'q', 材料を変更する場合は 'c' と入力): 5000
数値 '5000.0' のみが入力されました。各単位での計算結果を表示します。
▶ [鉄] の場合: 39.350 g (5000.0 ㎣)
▶ [鉄] の場合: 39.350 kg (5000.0 ㎤)
▶ [鉄] の場合: 39350.000 t (5000.0 ㎥)
------------------------------
体積を入力してください (例: 1500mm3, 2.5cm^3)
(終了する場合は 'q', 材料を変更する場合は 'c' と入力): q
スクリプトを終了します。ありがとうございました。
5. まとめと発展のヒント
今回は、実用的な「材料重量計算ツール」を題材に、Pythonプログラミングの様々な要素を組み合わせる実践的なプロジェクトに挑戦しました。
- 辞書を使った設定管理(密度、単位換算係数)
- 正規表現(
re
)を使った柔軟なユーザー入力の解析 - 関数による処理の部品化とコードの構造化
try-except
によるエラーハンドリング- f-stringを使った見やすい出力フォーマット
このスクリプトは、あなたの手でさらに改良することができます。例えば、
- 材料の追加:
DENSITIES
辞書に新しい材料(例: ‘銅’, ‘木材’など)とその密度を追加するだけで、簡単機能拡張できます。 - 形状からの体積計算: 「直径と長さを入力して円柱の体積を計算する」といった関数を追加してみる。
- GUI化: `Tkinter`(標準ライブラリ)や、より手軽な`PySimpleGUI`(外部ライブラリ)を使って、グラフィカルなアプリケーションにしてみる。
ぜひ、このスクリプトをベースにして、あなた自身のオリジナルツールを作ってみてください。プログラミングの本当の楽しさは、自分の手で便利なものを作り出すことにあります!
コメント