aW1wb3J0IHBhbmRhcyBhcyBwZApmcm9tIGRhdGV0aW1lIGltcG9ydCBkYXRldGltZQpmcm9tIGRlY2ltYWwgaW1wb3J0IERlY2ltYWwKZnJvbSB0YWJ1bGF0ZSBpbXBvcnQgdGFidWxhdGUKCiMgQ3JlYW1vcyB1bmEgbGlzdGEgZG9uZGUgc2UgZXN0YXImYWFjdXRlO24gZ3VhcmRhbmRvIHRvZG9zIGxvcyBtb3ZpbWllbnRvcwpsc3RfZGljY2lvbmFyaW9zID0gW10KCndoaWxlIFRydWU6CiAgICB0cnk6CiAgICAgICAgcHJpbnQoJnF1b3Q7LS0gTUVOVSBQUklOQ0lQQUwgLS0mcXVvdDspCiAgICAgICAgcHJpbnQoJnF1b3Q7MSAtIEFncmVnYXIgdW4gZWdyZXNvLiZxdW90OykKICAgICAgICBwcmludCgmcXVvdDsyIC0gQWdyZWdhciB1biBpbmdyZXNvLiZxdW90OykKICAgICAgICBwcmludCgmcXVvdDszIC0gTW9zdHJhciB0YWJsYSBkZSB0b2RvcyBsb3MgaW5ncmVzb3MgeSBlZ3Jlc29zLiZxdW90OykKICAgICAgICBwcmludCgmcXVvdDs0IC0gRXhwb3J0YXIgcHJlc3VwdWVzdG8gYSBDU1YgbyBFeGNlbC4mcXVvdDspCiAgICAgICAgcHJpbnQoJnF1b3Q7NSAtIFNhbGlyLiZxdW90OykKCiAgICAgICAgb3BjaW9uID0gaW50KGlucHV0KCZxdW90O0VsaWphIHVuYSBvcGNpJm9hY3V0ZTtuOiAmcXVvdDspKQoKICAgICAgICBpZiBvcGNpb24gPT0gMToKICAgICAgICAgICAgcHJpbnQoJnF1b3Q7LS0gTElTVEEgREUgRUdSRVNPUyAtLSZxdW90OykKICAgICAgICAgICAgcHJpbnQoJnF1b3Q7MSAtIFRyYW5zcG9ydGUuJnF1b3Q7KQogICAgICAgICAgICBwcmludCgmcXVvdDsyIC0gUGFnbyBkZSBleGFtZW5lcy4mcXVvdDspCiAgICAgICAgICAgIHByaW50KCZxdW90OzMgLSBHWU0uJnF1b3Q7KQogICAgICAgICAgICBwcmludCgmcXVvdDs0IC0gRGl2ZXJzaSZvYWN1dGU7biwgcmVjcmVhY2kmb2FjdXRlO24geSBzYWxpZGFzLiZxdW90OykKICAgICAgICAgICAgcHJpbnQoJnF1b3Q7NSAtIExpYnJvcyBvIGZvdG9jb3BpYXMuJnF1b3Q7KQogICAgICAgICAgICBwcmludCgmcXVvdDs2IC0gUmVncmVzYXIgYSBNZW51IFByaW5jaXBhbC4mcXVvdDspCgogICAgICAgICAgICBvcGNpb25fZWdyZXNvID0gRGVjaW1hbChpbnB1dCgmcXVvdDtFbGlqYSB1bmEgb3BjaSZvYWN1dGU7bjogJnF1b3Q7KSkKCiAgICAgICAgICAgIGlmIG9wY2lvbl9lZ3Jlc28gPT0gNjoKICAgICAgICAgICAgICAgIGJyZWFrCgogICAgICAgICAgICBjYW50aWRhZCA9IGZsb2F0KGlucHV0KCZxdW90O0NhbnRpZGFkOiAmcXVvdDspKQogICAgICAgICAgICBkdCA9IGRhdGV0aW1lLm5vdygpCiAgICAgICAgICAgIGZvcm1hdG8gPSAmcXVvdDslWS0lbS0lZCAlSDolTSZxdW90OwogICAgICAgICAgICBmZWNoYV9hY3R1YWwgPSBkdC5zdHJmdGltZShmb3JtYXRvKQoKICAgICAgICAgICAgY29uY2VwdG9zX2VncmVzbyA9IFsKICAgICAgICAgICAgICAgICdUcmFuc3BvcnRlJywKICAgICAgICAgICAgICAgICdQYWdvIGRlIGV4YW1lbmVzJywKICAgICAgICAgICAgICAgICdHWU0nLAogICAgICAgICAgICAgICAgJ0RpdmVyc2kmb2FjdXRlO24sIHJlY3JlYWNpJm9hY3V0ZTtuIHkgc2FsaWRhcycsCiAgICAgICAgICAgICAgICAnTGlicm9zIG8gZm90b2NvcGlhcycKICAgICAgICAgICAgXQoKICAgICAgICAgICAgZWdyZXNvID0gewogICAgICAgICAgICAgICAgJ0NvbmNlcHRvJzogY29uY2VwdG9zX2VncmVzb1tpbnQob3BjaW9uX2VncmVzbykgLSAxXSwKICAgICAgICAgICAgICAgICdDYW50aWRhZCc6IGNhbnRpZGFkLAogICAgICAgICAgICAgICAgJ0ZlY2hhJzogZmVjaGFfYWN0dWFsLAogICAgICAgICAgICAgICAgJ1RpcG9fTW92aW1pZW50byc6ICdFR1JFU08nCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxzdF9kaWNjaW9uYXJpb3MuYXBwZW5kKGVncmVzbykKICAgICAgICAgICAgZGYgPSBwZC5EYXRhRnJhbWUobHN0X2RpY2Npb25hcmlvcykKCiAgICAgICAgICAgIHByaW50KCZxdW90OyZpZXhjbDtOVUVWTyBFR1JFU08gR1VBUkRBRE8gQ09OICZFYWN1dGU7WElUTyEmcXVvdDspCiAgICAgICAgICAgIHByaW50KGRmKQoKICAgICAgICBlbGlmIG9wY2lvbiA9PSAyOgogICAgICAgICAgICBwcmludCgmcXVvdDstLSBMSVNUQSBERSBJTkdSRVNPUyAtLSZxdW90OykKICAgICAgICAgICAgcHJpbnQoJnF1b3Q7MSAtIFN1ZWxkby4mcXVvdDspCiAgICAgICAgICAgIHByaW50KCZxdW90OzIgLSBBcG9ydGFjaSZvYWN1dGU7biBkZSBwYXAmYWFjdXRlO3MuJnF1b3Q7KQogICAgICAgICAgICBwcmludCgmcXVvdDszIC0gVmVudGEgZGUgY29taWRhLiZxdW90OykKICAgICAgICAgICAgcHJpbnQoJnF1b3Q7NCAtIFRyYWJham8gZGUgbWVkaW8gdGllbXBvLiZxdW90OykKICAgICAgICAgICAgcHJpbnQoJnF1b3Q7NSAtIERhciB0dXRvciZpYWN1dGU7YXMuJnF1b3Q7KQogICAgICAgICAgICBwcmludCgmcXVvdDs2IC0gUmVncmVzYXIgYSBNZW51IFByaW5jaXBhbC4mcXVvdDspCgogICAgICAgICAgICBvcGNpb25faW5ncmVzbyA9IGludChpbnB1dCgmcXVvdDtFbGlqYSB1bmEgb3BjaSZvYWN1dGU7bjogJnF1b3Q7KSkKCiAgICAgICAgICAgIGlmIG9wY2lvbl9pbmdyZXNvID09IDY6CiAgICAgICAgICAgICAgICBicmVhawoKICAgICAgICAgICAgY2FudGlkYWQgPSBmbG9hdChpbnB1dCgmcXVvdDtDYW50aWRhZDogJnF1b3Q7KSkKICAgICAgICAgICAgZHQgPSBkYXRldGltZS5ub3coKQogICAgICAgICAgICBmb3JtYXRvID0gJnF1b3Q7JVktJW0tJWQgJUg6JU0mcXVvdDsKICAgICAgICAgICAgZmVjaGFfYWN0dWFsID0gZHQuc3RyZnRpbWUoZm9ybWF0bykKCiAgICAgICAgICAgIGNvbmNlcHRvc19pbmdyZXNvID0gWwogICAgICAgICAgICAgICAgJ1N1ZWxkbycsCiAgICAgICAgICAgICAgICAnQXBvcnRhY2kmb2FjdXRlO24gZGUgcGFwJmFhY3V0ZTtzJywKICAgICAgICAgICAgICAgICdWZW50YSBkZSBjb21pZGEnLAogICAgICAgICAgICAgICAgJ1RyYWJham8gZGUgbWVkaW8gdGllbXBvJywKICAgICAgICAgICAgICAgICdEYXIgdHV0b3ImaWFjdXRlO2FzJwogICAgICAgICAgICBdCgogICAgICAgICAgICBpbmdyZXNvID0gewogICAgICAgICAgICAgICAgJ0NvbmNlcHRvJzogY29uY2VwdG9zX2luZ3Jlc29bb3BjaW9uX2luZ3Jlc28gLSAxXSwKICAgICAgICAgICAgICAgICdDYW50aWRhZCc6IGNhbnRpZGFkLAogICAgICAgICAgICAgICAgJ0ZlY2hhJzogZmVjaGFfYWN0dWFsLAogICAgICAgICAgICAgICAgJ1RpcG9fTW92aW1pZW50byc6ICdJTkdSRVNPJwogICAgICAgICAgICB9CgogICAgICAgICAgICBsc3RfZGljY2lvbmFyaW9zLmFwcGVuZChpbmdyZXNvKQogICAgICAgICAgICBkZiA9IHBkLkRhdGFGcmFtZShsc3RfZGljY2lvbmFyaW9zKQoKICAgICAgICAgICAgcHJpbnQoJnF1b3Q7JmlleGNsO05VRVZPIElOR1JFU08gR1VBUkRBRE8gQ09OICZFYWN1dGU7WElUTyEmcXVvdDspCiAgICAgICAgICAgIHByaW50KGRmKQoKICAgICAgICBlbGlmIG9wY2lvbiA9PSAzOgogICAgICAgICAgICBjYW50aWRhZF9lbGVtZW50b3MgPSBsZW4obHN0X2RpY2Npb25hcmlvcykKICAgICAgICAgICAgaWYgY2FudGlkYWRfZWxlbWVudG9zID09IDA6CiAgICAgICAgICAgICAgICBwcmludCgmcXVvdDtBY3R1YWxtZW50ZSBubyBzZSBoYSBhZ3JlZ2FkbyBuaW5nJnVhY3V0ZTtuIG1vdmltaWVudG8gcGFyYSB2aXN1YWxpemFyLiZxdW90OykKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIGRmID0gcGQuRGF0YUZyYW1lKGxzdF9kaWNjaW9uYXJpb3MpCiAgICAgICAgICAgICAgICB0YWJsYV9jZW50cmFsaXphZGEgPSB0YWJ1bGF0ZShkZiwgaGVhZGVycz0na2V5cycsIHRhYmxlZm10PSdwcmV0dHknLCBzaG93aW5kZXg9RmFsc2UpCiAgICAgICAgICAgICAgICBwcmludCh0YWJsYV9jZW50cmFsaXphZGEpCgogICAgICAgIGVsaWYgb3BjaW9uID09IDQ6CiAgICAgICAgICAgIGNhbnRpZGFkX2VsZW1lbnRvcyA9IGxlbihsc3RfZGljY2lvbmFyaW9zKQogICAgICAgICAgICBpZiBjYW50aWRhZF9lbGVtZW50b3MgPT0gMDoKICAgICAgICAgICAgICAgIHByaW50KCZxdW90O0FjdHVhbG1lbnRlIG5vIHNlIGhhIGFncmVnYWRvIG5pbmcmdWFjdXRlO24gbW92aW1pZW50byBwYXJhIGV4cG9ydGFyLiZxdW90OykKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgICAgICAgICAgcHJpbnQoJnF1b3Q7MSAtIEV4cG9ydGFyIGEgQ1NWJnF1b3Q7KQogICAgICAgICAgICAgICAgICAgIHByaW50KCZxdW90OzIgLSBFeHBvcnRhciBhIEV4Y2VsJnF1b3Q7KQogICAgICAgICAgICAgICAgICAgIHByaW50KCZxdW90OzMgLSBSZWdyZXNhciBhIE1lbnUgUHJpbmNpcGFsLiZxdW90OykKCiAgICAgICAgICAgICAgICAgICAgb3BjaW9uX2V4cG9ydGFyID0gaW50KGlucHV0KCZxdW90O0VsaWphIHVuYSBvcGNpJm9hY3V0ZTtuOiAmcXVvdDspKQoKICAgICAgICAgICAgICAgICAgICBpZiBvcGNpb25fZXhwb3J0YXIgPT0gMToKICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnQoJnF1b3Q7SW5ncmVzYSBsYSBydXRhIGRvbmRlIGRlc2VhIGV4cG9ydGFyIHR1IGFyY2hpdm8mcXVvdDspCiAgICAgICAgICAgICAgICAgICAgICAgIHByaW50KCZxdW90O0VqZW1wbG86IEM6L1VzZXJzL1VzZXIvRGVza3RvcC9Gb2xkZXImcXVvdDspCiAgICAgICAgICAgICAgICAgICAgICAgIHJ1dGEgPSBpbnB1dCgmcXVvdDtSdXRhOiAmcXVvdDspCiAgICAgICAgICAgICAgICAgICAgICAgIGFyY2hpdm9fY3N2ID0gJnF1b3Q7YXJjaGl2b19jc3YuY3N2JnF1b3Q7CiAgICAgICAgICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRmLnRvX2NzdihydXRhICsgJnF1b3Q7LyZxdW90OyArIGFyY2hpdm9fY3N2LCBpbmRleD1GYWxzZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW50KGYnJmlleGNsO0FyY2hpdm8gZXhwb3J0YWRvIGV4aXRvc2FtZW50ZSBhIHtydXRhfS97YXJjaGl2b19jc3Z9IScpCiAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW50KGYnRXJyb3IgYWwgZXhwb3J0YXIgZWwgYXJjaGl2bzoge2V9JykKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsKCiAgICAgICAgICAgICAgICAgICAgZWxpZiBvcGNpb25fZXhwb3J0YXIgPT0gMjoKICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnQoJnF1b3Q7SW5ncmVzYSBsYSBydXRhIGRvbmRlIGRlc2VhIGV4cG9ydGFyIHR1IGFyY2hpdm8mcXVvdDspCiAgICAgICAgICAgICAgICAgICAgICAgIHByaW50KCZxdW90O0VqZW1wbG86IEM6L1VzZXJzL1VzZXIvRGVza3RvcC9Gb2xkZXImcXVvdDspCiAgICAgICAgICAgICAgICAgICAgICAgIHJ1dGEgPSBpbnB1dCgmcXVvdDtSdXRhOiAmcXVvdDspCiAgICAgICAgICAgICAgICAgICAgICAgIGFyY2hpdm9fZXhjZWwgPSAmcXVvdDthcmNoaXZvX2V4Y2VsLnhsc3gmcXVvdDsKICAgICAgICAgICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGYudG9fZXhjZWwocnV0YSArICZxdW90Oy8mcXVvdDsgKyBhcmNoaXZvX2V4Y2VsLCBpbmRleD1GYWxzZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW50KGYnJmlleGNsO0FyY2hpdm8gZXhwb3J0YWRvIGV4aXRvc2FtZW50ZSBhIHtydXRhfS97YXJjaGl2b19leGNlbH0hJykKICAgICAgICAgICAgICAgICAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnQoZidFcnJvciBhbCBleHBvcnRhciBlbCBhcmNoaXZvOiB7ZX0nKQogICAgICAgICAgICAgICAgICAgICAgICBicmVhawoKICAgICAgICAgICAgICAgICAgICBlbGlmIG9wY2lvbl9leHBvcnRhciA9PSAzOgogICAgICAgICAgICAgICAgICAgICAgICBicmVhawoKICAgICAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgICAgICBwcmludCgmcXVvdDtPcGNpJm9hY3V0ZTtuIG5vIHYmYWFjdXRlO2xpZGEuIFBvciBmYXZvciwgZWxpamEgdW5hIG9wY2kmb2FjdXRlO24gZGVsIDEgYWwgMy4mcXVvdDspCgogICAgICAgIGVsaWYgb3BjaW9uID09IDU6CiAgICAgICAgICAgIGJyZWFrCgogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHByaW50KCZxdW90O09wY2kmb2FjdXRlO24gbm8gdiZhYWN1dGU7bGlkYS4gUG9yIGZhdm9yLCBlbGlqYSB1bmEgb3BjaSZvYWN1dGU7biBkZWwgMSBhbCA1LiZxdW90OykKCiAgICBleGNlcHQgVmFsdWVFcnJvcjoKICAgICAgICBwcmludCgmcXVvdDtFcnJvcjogSW5ncmVzZSB1biB2YWxvciBudW0mZWFjdXRlO3JpY28gdiZhYWN1dGU7bGlkby4mcXVvdDspCiAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6CiAgICAgICAgcHJpbnQoZiZxdW90O0Vycm9yOiB7ZX0mcXVvdDspCg==
import pandas as pd
from datetime import datetime
from decimal import Decimal
from tabulate import tabulate
# Creamos una lista donde se estarán guardando todos los movimientos
lst_diccionarios = []
while True:
try:
print("-- MENU PRINCIPAL --")
print("1 - Agregar un egreso.")
print("2 - Agregar un ingreso.")
print("3 - Mostrar tabla de todos los ingresos y egresos.")
print("4 - Exportar presupuesto a CSV o Excel.")
print("5 - Salir.")
opcion = int(input("Elija una opción: "))
if opcion == 1:
print("-- LISTA DE EGRESOS --")
print("1 - Transporte.")
print("2 - Pago de examenes.")
print("3 - GYM.")
print("4 - Diversión, recreación y salidas.")
print("5 - Libros o fotocopias.")
print("6 - Regresar a Menu Principal.")
opcion_egreso = Decimal(input("Elija una opción: "))
if opcion_egreso == 6:
break
cantidad = float(input("Cantidad: "))
dt = datetime.now()
formato = "%Y-%m-%d %H:%M"
fecha_actual = dt.strftime(formato)
conceptos_egreso = [
'Transporte',
'Pago de examenes',
'GYM',
'Diversión, recreación y salidas',
'Libros o fotocopias'
]
egreso = {
'Concepto': conceptos_egreso[int(opcion_egreso) - 1],
'Cantidad': cantidad,
'Fecha': fecha_actual,
'Tipo_Movimiento': 'EGRESO'
}
lst_diccionarios.append(egreso)
df = pd.DataFrame(lst_diccionarios)
print("¡NUEVO EGRESO GUARDADO CON ÉXITO!")
print(df)
elif opcion == 2:
print("-- LISTA DE INGRESOS --")
print("1 - Sueldo.")
print("2 - Aportación de papás.")
print("3 - Venta de comida.")
print("4 - Trabajo de medio tiempo.")
print("5 - Dar tutorías.")
print("6 - Regresar a Menu Principal.")
opcion_ingreso = int(input("Elija una opción: "))
if opcion_ingreso == 6:
break
cantidad = float(input("Cantidad: "))
dt = datetime.now()
formato = "%Y-%m-%d %H:%M"
fecha_actual = dt.strftime(formato)
conceptos_ingreso = [
'Sueldo',
'Aportación de papás',
'Venta de comida',
'Trabajo de medio tiempo',
'Dar tutorías'
]
ingreso = {
'Concepto': conceptos_ingreso[opcion_ingreso - 1],
'Cantidad': cantidad,
'Fecha': fecha_actual,
'Tipo_Movimiento': 'INGRESO'
}
lst_diccionarios.append(ingreso)
df = pd.DataFrame(lst_diccionarios)
print("¡NUEVO INGRESO GUARDADO CON ÉXITO!")
print(df)
elif opcion == 3:
cantidad_elementos = len(lst_diccionarios)
if cantidad_elementos == 0:
print("Actualmente no se ha agregado ningún movimiento para visualizar.")
else:
df = pd.DataFrame(lst_diccionarios)
tabla_centralizada = tabulate(df, headers='keys', tablefmt='pretty', showindex=False)
print(tabla_centralizada)
elif opcion == 4:
cantidad_elementos = len(lst_diccionarios)
if cantidad_elementos == 0:
print("Actualmente no se ha agregado ningún movimiento para exportar.")
else:
while True:
print("1 - Exportar a CSV")
print("2 - Exportar a Excel")
print("3 - Regresar a Menu Principal.")
opcion_exportar = int(input("Elija una opción: "))
if opcion_exportar == 1:
print("Ingresa la ruta donde desea exportar tu archivo")
print("Ejemplo: C:/Users/User/Desktop/Folder")
ruta = input("Ruta: ")
archivo_csv = "archivo_csv.csv"
try:
df.to_csv(ruta + "/" + archivo_csv, index=False)
print(f'¡Archivo exportado exitosamente a {ruta}/{archivo_csv}!')
except Exception as e:
print(f'Error al exportar el archivo: {e}')
break
elif opcion_exportar == 2:
print("Ingresa la ruta donde desea exportar tu archivo")
print("Ejemplo: C:/Users/User/Desktop/Folder")
ruta = input("Ruta: ")
archivo_excel = "archivo_excel.xlsx"
try:
df.to_excel(ruta + "/" + archivo_excel, index=False)
print(f'¡Archivo exportado exitosamente a {ruta}/{archivo_excel}!')
except Exception as e:
print(f'Error al exportar el archivo: {e}')
break
elif opcion_exportar == 3:
break
else:
print("Opción no válida. Por favor, elija una opción del 1 al 3.")
elif opcion == 5:
break
else:
print("Opción no válida. Por favor, elija una opción del 1 al 5.")
except ValueError:
print("Error: Ingrese un valor numérico válido.")
except Exception as e:
print(f"Error: {e}")