ユーニックス総合研究所

  • home
  • archives
  • python-zosyokanri

Pythonで蔵書管理プログラムを作る【CUI】

  • 作成日: 2023-08-10
  • 更新日: 2023-12-24
  • カテゴリ: Python

Pythonで蔵書管理プログラムを作る【CUI】

毎日暑いですが皆さんいかがお過ごしでしょうか。
最近は暑さもマシになってきたかな? という感じがやっと出てきましたが、それでもまだ暑いです。
感覚がマヒしてるんですね、きっと。

今回は暑いのでPythonで蔵書管理プログラムを作りました。
そのソースコードを掲載し、解説します。

関連記事
Djangoでオブジェクトを一括作成・更新【bulk_create, bulk_update】
DjangoのModel.objects.filter()の使い方【QuerySet】
Djangoのmodelのcreate()の使い方【Python】
Django入門: ルートの設定 ~ 簡単な一行掲示板アプリを作る その4【Windows10】
NumPyのappend()の使い方: 配列の末尾に要素を追加
Numpyのarangeの使い方: 指定範囲の数列を生成する
Python3でYoutube Data APIを使ってキーワード検索する
PythonからC言語(my.puts)を呼び出して実行する

動かしているところ

プログラムを動かすと以下のようなに感じなります。

蔵書管理: 見る(0) 追加(1) 削除(2) > 0  
蔵書管理: 見る(0) 追加(1) 削除(2) > 1  
蔵書を追加します。  
タイトル > ababa  
説明 > hige  
蔵書管理: 見る(0) 追加(1) 削除(2) > 0  
ababa  
hige  
----------------------------------------  
蔵書管理: 見る(0) 追加(1) 削除(2) > 1  
蔵書を追加します。  
タイトル > ugogo  
説明 > huge  
蔵書管理: 見る(0) 追加(1) 削除(2) > 0  
ababa  
hige  
----------------------------------------  
ugogo  
huge  
----------------------------------------  
蔵書管理: 見る(0) 追加(1) 削除(2) > 2  
蔵書を削除します。  
タイトル > ugogo  
蔵書管理: 見る(0) 追加(1) 削除(2) > 0  
ababa  
hige  
----------------------------------------  
蔵書管理: 見る(0) 追加(1) 削除(2) >  

番号で「見る、追加、削除」を選択して蔵書を見たり追加したりします。
コンソールアプリですので端末上で動きます。
データーベースはJSONで作成し管理します。お手軽ですね。

ソースコード全文

以下がソースコード全文です。

import json  
import os  


DB_NAME = 'data.json'  


def touch_db():  
    if not os.path.exists(DB_NAME):  
        with open(DB_NAME, 'w', encoding='utf-8') as fout:  
            fout.write('{ "books": [] }')  


def load_db():  
    touch_db()  
    with open(DB_NAME, 'r', encoding='utf-8') as fin:  
        return json.load(fin)  


def save_db(d: dict):  
    with open(DB_NAME, 'w', encoding='utf-8') as fout:  
        fout.write(json.dumps(d))  


def see():  
    db = load_db()  
    books = db['books']  

    for book in books:  
        print(book['title'])  
        print(book['description'])  
        print('-' * 40)  


def add():  
    print('蔵書を追加します。')  
    title = input('タイトル > ')  
    description = input('説明 > ')  
    book = {  
        'title': title,  
        'description': description,  
    }  

    db = load_db()  
    db['books'].append(book)  
    save_db(db)  


def remove():  
    print('蔵書を削除します。')  
    title = input('タイトル > ')  

    db = load_db()  
    books = db['books']  

    dst = []  
    for book in books:  
        if title == book['title']:  
            pass  
        else:  
            dst.append(book)  

    db['books'] = dst  
    save_db(db)  


def main():  
    while True:  
        try:  
            cmd = input('蔵書管理: 見る(0) 追加(1) 削除(2) > ')  
        except KeyboardInterrupt:  
            break  

        cmd = int(cmd)  
        if cmd == 0:  
            see()  
        elif cmd == 1:  
            add()  
        elif cmd == 2:  
            remove()  


main()  

main関数

プログラムはmain関数から始まります。

def main():  
    while True:  
        try:  
            cmd = input('蔵書管理: 見る(0) 追加(1) 削除(2) > ')  
        except KeyboardInterrupt:  
            break  

        cmd = int(cmd)  
        if cmd == 0:  
            see()  
        elif cmd == 1:  
            add()  
        elif cmd == 2:  
            remove()  


main()  

この関数では無限ループを作り、コマンドを処理します。
コマンドの入力はinput()で行います。
このinput関数は標準入力から一行文字列として読み取る関数です。

cmdに読み取った文字列を保存したらそれをint(cmd)で整数に変換します。
そしてcmdの値に応じてsee(), add(), remove()関数を呼び出します。

see関数

see関数は蔵書情報を閲覧する関数です。

def see():  
    db = load_db()  
    books = db['books']  

    for book in books:  
        print(book['title'])  
        print(book['description'])  
        print('-' * 40)  

この関数ではまずload_db()でデータを読み込みます。
そしてデータの辞書からbooksを取り出します。これはリストです。
そしてfor文でbooksを回し、titledescriptionを出力します。
print('-' * 40)とやるとハイフンを40個出力します。

load_db関数

def load_db():  
    touch_db()  
    with open(DB_NAME, 'r', encoding='utf-8') as fin:  
        return json.load(fin)  

この関数はデータベースを読み込みます。
データベースはDB_NAMEの名前のJSONファイルです。

DB_NAME = 'data.json'  

touch_db()でファイルが無い場合は作成しています。
ファイルをopen()で開いたらファイルオブジェクトをjson.load()でパースして辞書に変換します。

open()は第1引数がファイル名、第2引数がオープンモード、encoding引数が文字コードの指定です。
オープンモードはrだとテキストファイルの読み込み、wだとテキストファイルの書き込みになります。
wはファイルを空にしますので、既存のファイルが存在する場合は注意が必要です。

またencodingutf-8にします。
Linuxではデフォルトでutf-8になるんですが、Windowsではcp932になります。
ですのでUTF-8でファイルを扱いたい場合はこの指定が必要です。

touch_db関数

def touch_db():  
    if not os.path.exists(DB_NAME):  
        with open(DB_NAME, 'w', encoding='utf-8') as fout:  
            fout.write('{ "books": [] }')  

この関数はDB_NAMEのファイルが存在しない場合に、空のデータベースを作成します。
os.path.exists()はファイルが存在するときにTrueを返します。
ファイルが存在しなかったらファイルを書き込みモードで開き、ファイル内容を書き込みます。
ファイル内容は

{ "books": [] }  

になっており、これはJSONのフォーマットを満たすものです。
空のbooksを入れていますが、こうしておくと面倒な処理が減ります。

add関数

def add():  
    print('蔵書を追加します。')  
    title = input('タイトル > ')  
    description = input('説明 > ')  
    book = {  
        'title': title,  
        'description': description,  
    }  

    db = load_db()  
    db['books'].append(book)  
    save_db(db)  

この関数は蔵書データをデータベースに保存します。
input()で蔵書のタイトルと説明を読み取ります。
それをbookという辞書にして読み込んだデータベースのbooksに追加します。
追加したらsave_db()で辞書をファイルに保存します。

save_db関数

def save_db(d: dict):  
    with open(DB_NAME, 'w', encoding='utf-8') as fout:  
        fout.write(json.dumps(d))  

この関数は引数の辞書をデータベースとして保存します。
open()wモードはファイルを空にして書き込みしますが、dには全データが入っている前提の設計なので問題ないです。
実用的なアプリではこういった設計はあまり見られませんが、このような簡易的なアプリではよくあります。

辞書はjson.dumps()で文字列にできます。
それを開いたファイルにfout.write()で保存します。

ちなみにfinfile inputfoutfile outputの略です。

remove関数

def remove():  
    print('蔵書を削除します。')  
    title = input('タイトル > ')  

    db = load_db()  
    books = db['books']  

    dst = []  
    for book in books:  
        if title == book['title']:  
            pass  
        else:  
            dst.append(book)  

    db['books'] = dst  
    save_db(db)  

remove関数は蔵書データを削除します。
削除対処の蔵書のタイトルを入植してもらい、それをbooksから検索し、ヒットしたらdstに保存しないようにします。
dstにはヒットした蔵書以外の蔵書データが保存されますので、あとはこれをbooksに代入し、その辞書をsave_db()で保存します。

おわりに

今回はPythonで蔵書管理プログラムを作りました。
なにか参考になれば幸いです。

🦝 < 蔵書を管理するぞ!

🦝 < どうぞ