ブログ

  • Pythonのインストール方法【初心者向けガイド】

    この記事で分かること

    • WindowsパソコンへのPythonのインストール手順
    • 初心者でも迷わないインストーラーの選び方
    • コマンド操作が苦手な人でも分かるセットアップ方法
    • よくあるトラブルの対処法

    Pythonのインストール手順

    1. Pythonとは?

    **Python(パイソン)**は、初心者からプロまで幅広く使われている人気のプログラミング言語です。
    データ分析・自動化・Webアプリ開発など、さまざまな用途に利用されています。


    2. インストーラーのダウンロード

    1. 公式サイト(https://www.python.org/)にアクセスします。
    2. 画面上部の「Downloads」をクリックし、「Python 3.x.x」のボタンから最新版をダウンロードします。
      ※「x.x」はバージョン番号です。基本的に一番上に表示されている最新版でOKです。

    3. インストーラーの実行

    1. ダウンロードしたファイル(例:python-3.x.x.exe)をダブルクリックします。
    1. 最初の画面で、「Add Python 3.x to PATH」 に必ずチェックを入れてから「Install Now」をクリックします。
      • ※このチェックを入れることで、コマンドプロンプトから「python」コマンドがすぐ使えるようになります。
    2. インストールが始まるので、数分待ちます。

    4. インストール完了の確認

    1. インストールが終わったら、「Close」ボタンをクリックしてインストーラーを閉じます。
    2. 「スタートメニュー」→「Windowsシステムツール」→「コマンドプロンプト」を開きます。
    3. 下記のコマンドを入力して、バージョン情報が表示されれば成功です。
    python --version

    例)

    Python 3.12.3

    よくあるトラブル・注意点

    Q. 「pythonが見つかりません」と表示された場合は?
    A. インストール時に「Add Python 3.x to PATH」にチェックを入れていないと、コマンドが認識されません。もう一度インストールを実行してチェックを入れ直しましょう。

    Q. 32bitと64bit、どちらを選べばいい?
    A. 基本的に「64bit」を選べば問題ありません。パソコンが古い場合や分からない場合は「自動選択」でOKです。


    まとめ・関連情報

    • Pythonは公式サイトから無料でインストール可能
    • 初心者は「PATHに追加」を必ずチェック
  • Pythonスクリプトを一発起動!相対パスでバッチファイル(.bat)を作ると超便利

    Pythonで作業していると、「毎回コマンドプロンプトでフォルダ移動→スクリプト実行」を繰り返すのは面倒ですよね。
    特に、パスが長かったり複数のプロジェクトを扱っている場合は、手間も増えてストレスの原因に。
    そんな悩みを解決するのが「バッチファイル(.bat)」です。本記事では、バッチファイルを相対パスで作成するメリットと、具体的な作成方法、実践例をわかりやすく解説します。

    .pyをコマンドプロンプトで毎回起動するのは面倒くさいですよね?

    Pythonスクリプトを実行するたびに、コマンドプロンプトを開いて

    cd C:\Users\user\project
    python main.py

    などと入力するのは意外と手間がかかります。
    毎回パスを指定したり、タイポでエラーになったり、ちょっとした作業でも時間がかかりがちです。

    相対パスでbatファイル作ると起動が便利ですよ

    こんな時におすすめなのが**バッチファイル(.batファイル)**の活用です。
    バッチファイルを作成すれば、ダブルクリック一発でPythonスクリプトが自動実行できます。
    しかも、「相対パス」で記述することで、フォルダごとコピーしたり、パソコンを変えてもそのまま使えます。
    複数人でファイルを共有する場合や、後でフォルダ構造を変更する場合にもとても便利です。

    batファイルの作成方法(初心者向けに解説)

    バッチファイルは、メモ帳などのテキストエディタで簡単に作成できます。手順は以下の通りです。

    1. メモ帳などでテキストファイルを作成

    1. デスクトップや任意のフォルダで右クリック → 「新規作成」 → 「テキスト ドキュメント」を選択
    2. 例として run.txt などの名前で保存します(ファイル名は日本語でもOKですが、後述の理由で半角英数字推奨です)

    2. バッチファイルの中身を書き込む

    作成したテキストファイルをダブルクリックして開き、以下の内容を書きます。

    @echo off
    python main.py
    pause

    ポイント
    上記の例では「main.py」を実行しますが、同じフォルダ内の別のPythonファイルを実行したい場合は、そのファイル名(例:sample.py)を書き込むだけでOKです。

    たとえば sample.py を実行したい場合は次のように書き換えます。

    @echo off
    python sample.py
    pause

    書き終わったら「ファイル」→「上書き保存」で保存しましょう。

    3. 拡張子を「.bat」に変更

    保存したテキストファイル(例:run.txt)を右クリック → 「名前の変更」で
    run.bat に拡張子を変更します。

    注意
    拡張子が表示されていない場合は、エクスプローラーの「表示」タブから「ファイル名拡張子」にチェックを入れてください。
    これで.txtが見えるようになります。

    4. バッチファイルを実行

    バッチファイルをダブルクリックすれば、書き込んだ.pyファイルが一発で実行されます。
    ファイル名は「run.bat」でも「スタート.bat」でも、日本語でもOKですが、できれば半角英数字のファイル名をおすすめします(エラーや不具合が起きにくいため)。


    コード例

    基本パターン(同じフォルダの場合)

    @echo off
    python main.py
    pause
    • @echo off :コマンドの表示をオフにします(なくても動作します)
    • python main.py :main.py を実行します
    • pause :スクリプト実行後に画面がすぐ閉じるのを防ぎます

    サブフォルダの場合

    例えば src フォルダの中に main.py がある場合は

    @echo off
    python src\main.py
    pause

    このように書けばOKです。

    ワンポイント

    • Pythonのパスが通っていない場合や、「pythonが見つかりません」と表示された場合は、py main.py としてもOKです
    • パスやファイル名にスペースや日本語が含まれている場合は、"src\サンプル スクリプト.py" のようにダブルクォーテーションで囲むと安心です

    まとめ

    • Pythonスクリプトを毎回コマンドプロンプトから手動で起動する手間を省ける
    • バッチファイルを使えば、ダブルクリック一発で自動実行できて作業効率がアップ
    • 相対パスで書くことで、フォルダの移動や共有、コピーにも柔軟に対応できる
    • 実行したい.pyファイル名を書き換えるだけで、どのスクリプトにも使い回し可能

    ぜひ一度試してみてください!

  • PDFの圧縮/分解/結合ツール

    PDFの圧縮/分解/結合ツール

    このツール(PDFTool)は、PDFや画像ファイルをドラッグ&ドロップで操作できる多機能PDFユーティリティです。
    主な特徴・機能を簡単にまとめます。


    何ができるツール?

    • PDFファイルや画像(JPEG, PNG)をウィンドウにドラッグ&ドロップしてリスト化
    • ファイルの並べ替えや削除が簡単(リスト上で順番を変えたりDeleteキーで削除)
    • 各ボタンでPDFファイルや画像ファイルに対し次の操作ができる:

    主な機能

    ボタン機能の説明
    🔻 圧縮選択したPDFを**軽量化(圧縮)**して別フォルダに保存します。
    📎 結合複数のPDFを一つのPDFに結合+圧縮して保存します。
    📂 分解1つのPDFをページごとに分割し、それぞれ圧縮したPDFとして保存します。
    🖼️→📄 画像PDF選択した画像(jpg/png)を
    PDF化して保存します。

    使い方

    1. 起動するとウィンドウが表示されます。
    2. PDFや画像ファイルをウィンドウ内にドラッグ&ドロップ → ファイルリストに追加されます。
    3. ファイルリスト内で並べ替えや選択・削除が可能。
    4. 実行したい処理のボタンを押すと、出力先のフォルダまたは保存先を指定し、処理が始まります。

    技術的な特徴

    • GUI(ウィンドウ操作)は PyQt5 で作成
    • PDF処理には PyPDF2、画像処理には Pillow(PIL) を利用
    • PDFの圧縮処理は Ghostscript をコマンドラインで呼び出して実行
      (Ghostscriptが必要、Windowsはgswin64cを自動認識)
    • すべての操作がGUIで直感的に可能

    代表的なユースケース

    • スキャンした大量のPDFを軽くしたいとき
    • バラバラのPDFや画像を一つのPDFにまとめたいとき
    • 1つのPDFを1ページずつバラして管理したいとき
    • JPEG/PNG画像をPDF化したいとき

    注意点

    • PDFの圧縮機能を使うにはGhostscriptのインストールが必要
    • 圧縮・分解・結合は「PDFのみ」対象(画像はPDF変換だけ)

    「PDFや画像ファイルの整理・圧縮・変換を直感的な操作で一括でこなしたい」人におすすめのツールです!
    シンプル操作なので初心者でも迷いません。

    import sys
    import os
    import subprocess
    from PyQt5.QtWidgets import (
        QApplication, QWidget, QVBoxLayout, QListWidget, QPushButton,
        QFileDialog, QGridLayout, QMessageBox, QLabel
    )
    from PyQt5.QtCore import Qt
    from PyPDF2 import PdfMerger, PdfReader, PdfWriter
    from PIL import Image
    
    class PDFTool(QWidget):
        def __init__(self):
            super().__init__()
            self.setWindowTitle("PDFツール - ドラッグ&ドロップ対応")
            self.setAcceptDrops(True)
            self.resize(600, 400)
    
            self.list_widget = QListWidget()
            self.list_widget.setDragDropMode(QListWidget.InternalMove)
            self.list_widget.setSelectionMode(QListWidget.SingleSelection)
            self.list_widget.installEventFilter(self)
    
            self.label = QLabel("PDFまたは画像をここにドラッグ&ドロップして並び替え可能\n選択してDeleteキーで削除できます")
            self.label.setAlignment(Qt.AlignCenter)
    
            self.btn_compress = QPushButton("🔻 圧縮")
            self.btn_merge = QPushButton("📎 結合")
            self.btn_split = QPushButton("📂 分解")
            self.btn_image_to_pdf = QPushButton("🖼️→📄 画像PDF")
    
            self.btn_compress.clicked.connect(self.compress_pdfs)
            self.btn_merge.clicked.connect(self.merge_pdfs)
            self.btn_split.clicked.connect(self.split_pdfs)
            self.btn_image_to_pdf.clicked.connect(self.image_to_pdf_only)
    
            layout = QVBoxLayout()
            layout.addWidget(self.label)
            layout.addWidget(self.list_widget)
    
            grid = QGridLayout()
            grid.addWidget(self.btn_compress, 0, 0, 1, 2)
            grid.addWidget(self.btn_merge, 1, 0, 1, 2)
            grid.addWidget(self.btn_split, 2, 0, 1, 2)
            grid.addWidget(self.btn_image_to_pdf, 3, 0, 1, 2)
            layout.addLayout(grid)
            self.setLayout(layout)
    
        def eventFilter(self, obj, event):
            if obj == self.list_widget and event.type() == event.KeyPress:
                if event.key() == Qt.Key_Delete:
                    for item in self.list_widget.selectedItems():
                        self.list_widget.takeItem(self.list_widget.row(item))
                    return True
            return super().eventFilter(obj, event)
    
        def dragEnterEvent(self, event):
            if event.mimeData().hasUrls():
                event.acceptProposedAction()
    
        def dropEvent(self, event):
            for url in event.mimeData().urls():
                path = url.toLocalFile()
                if path.lower().endswith((".pdf", ".jpg", ".jpeg", ".png")):
                    self.list_widget.addItem(path)
    
        def get_output_dir(self):
            output_dir = QFileDialog.getExistingDirectory(self, "出力フォルダを選択")
            return output_dir if output_dir else None
    
        def compress_pdf(self, input_path, output_path, quality="ebook"):
            gs_command = "gswin64c" if sys.platform.startswith("win") else "gs"
            cmd = [
                gs_command, "-sDEVICE=pdfwrite", "-dCompatibilityLevel=1.4",
                f"-dPDFSETTINGS=/{quality}", "-dNOPAUSE", "-dQUIET", "-dBATCH",
                f"-sOutputFile={output_path}", input_path
            ]
            try:
                subprocess.run(cmd, check=True, creationflags=subprocess.CREATE_NO_WINDOW if sys.platform.startswith("win") else 0)
                return True
            except FileNotFoundError:
                QMessageBox.critical(self, "Ghostscript エラー", "Ghostscript (gswin64c) が見つかりません。パスが通っているか確認してください。")
                return False
            except Exception as e:
                QMessageBox.critical(self, "圧縮エラー", f"{input_path}\n{e}")
                return False
    
        def compress_pdfs(self):
            output_dir = self.get_output_dir()
            if not output_dir:
                return
            for i in range(self.list_widget.count()):
                path = self.list_widget.item(i).text()
                if path.lower().endswith(".pdf"):
                    name = os.path.splitext(os.path.basename(path))[0] + "_compressed.pdf"
                    out_path = os.path.join(output_dir, name)
                    self.compress_pdf(path, out_path)
            QMessageBox.information(self, "完了", "圧縮完了")
    
        def merge_pdfs(self):
            paths = [self.list_widget.item(i).text() for i in range(self.list_widget.count()) if self.list_widget.item(i).text().lower().endswith(".pdf")]
            if not paths:
                return
            save_path, _ = QFileDialog.getSaveFileName(self, "保存先(結合+圧縮)", "", "PDF Files (*.pdf)")
            if not save_path:
                return
    
            temp_path = save_path + ".temp.pdf"
            merger = PdfMerger()
            for path in paths:
                merger.append(path)
            merger.write(temp_path)
            merger.close()
    
            success = self.compress_pdf(temp_path, save_path)
            if os.path.exists(temp_path):
                os.remove(temp_path)
    
            if success:
                QMessageBox.information(self, "完了", f"結合+圧縮完了: {save_path}")
            else:
                QMessageBox.warning(self, "失敗", "圧縮に失敗しました")
    
        def split_pdfs(self):
            output_dir = self.get_output_dir()
            if not output_dir:
                return
            for i in range(self.list_widget.count()):
                path = self.list_widget.item(i).text()
                if path.lower().endswith(".pdf"):
                    base_name = os.path.splitext(os.path.basename(path))[0]
                    compressed_path = os.path.join(output_dir, f"{base_name}_compressed.pdf")
                    success = self.compress_pdf(path, compressed_path)
                    if not success or not os.path.exists(compressed_path):
                        continue
                    try:
                        reader = PdfReader(compressed_path)
                        for j, page in enumerate(reader.pages):
                            writer = PdfWriter()
                            writer.add_page(page)
                            name = f"{base_name}_p{j+1}.pdf"
                            out_path = os.path.join(output_dir, name)
                            with open(out_path, "wb") as f:
                                writer.write(f)
                    except Exception as e:
                        QMessageBox.warning(self, "分解エラー", f"{path} の分解に失敗しました。\n{e}")
                    finally:
                        if os.path.exists(compressed_path):
                            os.remove(compressed_path)
            QMessageBox.information(self, "完了", "圧縮+分解完了")
    
        def image_to_pdf_only(self):
            output_dir = self.get_output_dir()
            if not output_dir:
                return
            for i in range(self.list_widget.count()):
                path = self.list_widget.item(i).text()
                if path.lower().endswith((".jpg", ".jpeg", ".png")):
                    try:
                        image = Image.open(path).convert("RGB")
                        base_name = os.path.splitext(os.path.basename(path))[0]
                        pdf_path = os.path.join(output_dir, base_name + ".pdf")
                        image.save(pdf_path)
                    except Exception as e:
                        QMessageBox.warning(self, "画像変換エラー", f"{path} の変換に失敗しました。\n{e}")
            QMessageBox.information(self, "完了", "画像をPDFに変換完了")
    
    if __name__ == '__main__':
        import ctypes
        if sys.platform.startswith("win"):
            ctypes.windll.user32.ShowWindow(ctypes.windll.kernel32.GetConsoleWindow(), 0)
    
        app = QApplication(sys.argv)
        tool = PDFTool()
        tool.show()
        sys.exit(app.exec_())