Googleレンズと連携したレシート管理のプロトタイプ(その2)

プログラミング

前回の続きで、今回は、実際のレシートを使っての操作と画面を紹介します。
また、当プロトタイプのPythonコードを最後に載せておきます。
Pythonコードの解説については、次回掲載します。
解説する内容は、私の忘備録ということで、私が忘れてしまいそうなことについて解説する予定です。
ただ、他にもすることがあるので、掲載は少し間を置くかもしれません。

Googleレンズを起動する前に、パソコン側でChromeを起動しておきます。
AnacondaからJupyter Notebookを起動して、プログラムも起動しておきましょう。

Chromeが起動していないと、スマホで翻訳したテキストデータをパソコンに送れません。
遅くとも、スマホ側で「パソコンにコピー」の操作をする前にChromeを起動しておく必要があります。

まず、スマホ側の操作です。
なお、私の使用しているスマートフォンはAndroidです。

スマホ側の操作について

Googleレンズのアイコンをタップします。

Googleレンズが起動したら「カメラで検索」をタップしてレシートを撮影します。

撮影するときはレシートがしわにならないよう、良く伸ばして行うことが、翻訳精度の向上につながります。

撮影したら翻訳する範囲を選択します。

[テキストを選択]と出てきたら、そこをタップします。

続いて、下図の操作で[パソコンにコピー]をタップすることで、パソコンに翻訳したテキストデータが送られます。

ここからはパソコンの操作です。
(Jupyuter Notebookでプログラムを既に起動しているものとします。)

パソコン側の操作

① TextAreaに翻訳テキストデータを貼り付けて編集します

TextAreaにCtrl + V で翻訳テキストデータを貼り付けます。

貼り付けたデータを1アイテムが品名、単価、数量(1アイテム3行)になるように編集します。
誤翻訳があれば修正し、不足データがあれば加筆します。
編集が完了したら[次へ]ボタンをクリックします。

② 共通項目を入力します

レシートの共通項目である購入日、購入店、支払区分を入力し、[次へ]をクリックします。

③ スプレッドシートに科目コードと税区分を入力します

翻訳テキストデータに②で入力した共通項目のデータを加え、さらに科目コードと税区分の項目を加えたスプレッドシートが表示されます。
このスプレッドシートの「科目コード」と「税区分」にデータを入力します。

入力が完了したら[DBに登録]ボタンをクリックします。
スプレッドシートのデータがデータベーステーブルに登録されます。

④ MySQLで登録状況を確認します

以上がスマホ側とパソコン側の操作です。
10アイテムのレシートでしたが、5分とかかりませんでした。
今回のケースでは、手入力と比べれば、はるかに楽で時間もかかりませんでした。(毎日できるかは別問題)
特に老眼の身には、レシートの細かい文字を認識して入力するのは、大変な肉体的、精神的な苦痛を伴うものなのです。
それは、大分解消されました。

最後に、パソコン側のPythonプログラム(プロトタイプ)を掲載しておきます。

from ipywidgets import Textarea, Button, VBox, widgets
from IPython.display import display, clear_output
import ipysheet
import mysql.connector
from datetime import datetime

# グローバル変数の定義
global Input, input_textarea, input_date, input_shop, input_payment, dblists


# Textareaウィジェットの設定
#
textarea = Textarea()
def get_input(change):
    global Input
    Input = change["new"]
textarea.observe(get_input, names='value')

#
# 購入情報の入力ウィジェットの設定
#
purchase_date = widgets.Text(description='購入日')
shop = widgets.Text(description='購入店')
payment = widgets.Text(description='支払区分')

#
# タイトルラベルの設定
#
title_label = widgets.Label(value="購入情報を入力してください")

#
# OKボタンの設定
#
next1_button = Button(description='次へ')
next2_button = Button(description='次へ')
save_button = Button(description='DBに登録')

#
# データベース接続情報を設定
#
db_config = {
    "host": "localhost",
    "user": "root",
    "password": "root",
    "database": "receipt"
}

#
# 初期画面(TextArea)表示
#
display(VBox([textarea, next1_button]))

########################################################
# ボタンがクリックされたときの処理
########################################################
def on_button_click(b):
    global input_date,  input_textarea, input_shop, input_payment, dblists
    
    if b == next1_button:
        clear_output()  # 既存のウィジェットをクリア
        #global input_date,  input_textarea, input_shop, input_payment
        input_textarea = Input.split('\n')
        input_date = purchase_date.value
        input_shop = shop.value
        input_payment = payment.value
        display(VBox([title_label, purchase_date, shop, payment, next2_button]))
        print(input_date)
    elif b == next2_button:
        input_date = purchase_date.value
        input_shop = shop.value
        input_payment = payment.value
        clear_output()  # 既存のウィジェットをクリア
        #1行のリストを品名、単価、数量を1組とするサブリストに分割する
        sublists = list(split_list(input_textarea, 3))
        #品名、単価、数量に列を追加する
        dblists = add_columnse(sublists, input_date, input_shop, input_payment)
        display_sheet(dblists)
    # DBへ登録ボタンが押されたときの処理をここに追加
    elif b == save_button:
        save_data(dblists)

#
# ボタンにクリックイベントを設定
#
next1_button.on_click(on_button_click)
next2_button.on_click(on_button_click)
save_button.on_click(on_button_click)
        
########################################################
#1行のリストを品名、単価、数量を1組とするサブリストに分割する処理
########################################################
def split_list(lst, chunk_size):
    chunk = []
    for val in lst:
        if len(chunk) == chunk_size:
            yield chunk
            chunk = []
        chunk.append(val)
    if chunk:
        yield chunk

########################################################
# リストに購入日,店,支払区分などの列を追加
########################################################
def add_columnse(list, input_date, input_shop, input_payment):
    date = input_date
    shop = input_shop
    payment = input_payment
    l1=list

    # 列を追加
    #日付、店、品名、単価、数量、金額、科目コード、税区分、支払区分、備考
    l2 = [[date, shop, item[0], item[1], item[2], str(int(item[1]) * int(item[2])), '', '',payment,''] for item in l1]
    return l2

########################################################
# シートにリストのデータを表示する処理
########################################################
def display_sheet(dblists):
    r=len(dblists)+1
    c=len(dblists[0])
    sheet1 = ipysheet.sheet(rows=r, columns=c)
    # タイトル名
    ipysheet.cell(0, 0, "年月日", type="text")
    ipysheet.cell(0, 1, "店名", type="text")
    ipysheet.cell(0, 2, "品名", type="text")
    ipysheet.cell(0, 3, "単価", type="text")
    ipysheet.cell(0, 4, "数量", type="text")
    ipysheet.cell(0, 5, "金額", type="text")
    ipysheet.cell(0, 6, "科目コード", type="text")
    ipysheet.cell(0, 7, "税区分", type="text")
    ipysheet.cell(0, 8, "支払区分", type="text")
    ipysheet.cell(0, 9, "備考", type="text")

    # セルを整数の添え字で指定
    for i in range(len(dblists)):
        for j in range(len(dblists[0])):
            dblists[i][j] = ipysheet.cell(i+1, j, dblists[i][j], type="text")

    display(VBox([save_button, sheet1]))

########################################################
# シートデータをDBテーブル(receipt)に登録する処理
########################################################
def save_data(dblists):
    l1 = dblists

    # データベースに接続
    #conn = mysql.connector.connect(**db_config)
    if __name__ == "__main__":
        host = "localhost"
        user = "root"
        password = "root"
        database = "receipt"

        db_connection = create_db_connection(host, user, password, database)
        if db_connection:
            cursor = db_connection.cursor()

            # リストの要素をテーブルに挿入
            insert_query = """
            INSERT INTO receipt (purchasedate, shop, itemname, price, quantity, amount, kamokucode, zeikubun, paymentcode, remarks)
            VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
            """
            for row in l1:
                date_cell, shop_cell, itemname_cell, price_cell, quantity_cell, amount_cell, kamokucode_cell, zeikubun_cell, paymentc_cell, remarks_cell = row
        
                # Cellオブジェクトから値を抽出
                date_str = date_cell.value
                shop_str = shop_cell.value
                itemname_str = itemname_cell.value
                price_val = price_cell.value
                quantity_val = quantity_cell.value
                amount_val = amount_cell.value
                kamokucode_str = kamokucode_cell.value
                zeikubun_str = zeikubun_cell.value
                paymentc_str = paymentc_cell.value
                remarks_str = remarks_cell.value

                # 日付を適切なフォーマットに変換
                date_obj = datetime.strptime(date_str, "%Y/%m/%d").date()
        
                # SQLクエリの実行

                try:
                    # SQLクエリの実行
                    cursor.execute(
                        insert_query, 
                        (
                            date_obj, 
                            shop_str, 
                            itemname_str, 
                            price_val, 
                            quantity_val, 
                            amount_val, 
                            kamokucode_str, 
                            zeikubun_str, 
                            paymentc_str, 
                            remarks_str
                        )
                    )
                except mysql.connector.Error as err:
                    print(f"Error: '{err}'")

            # コミットして変更を確定
            db_connection.commit()

            # 接続を閉じる
            db_connection.close()


########################################################
# データベースに接続する処理
########################################################
def create_db_connection(host_name, user_name, user_password, db_name):
    connection = None
    try:
        connection = mysql.connector.connect(
            host=host_name,
            user=user_name,
            passwd=user_password,
            database=db_name
            
        )
    except mysql.connector.Error as err:
        print(f"Error: '{err}'")

    return connection


前へ Googleレンズと連携したレシート管理のプロトタイプ(その1)
次へ Googleレンズと連携したレシート管理のプロトタイプ(その3)

タイトルとURLをコピーしました