first commit

This commit is contained in:
Auric Vente 2024-07-18 00:51:11 -06:00
commit 69acfd0389
9 changed files with 252 additions and 0 deletions

6
.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
venv/*
.directory
*.pyc
__pycache__/
.mypy_cache/
ants.db

68
ants.py Normal file
View File

@ -0,0 +1,68 @@
from __future__ import annotations
import utils
from database import Database
class Ant:
def __init__(self) -> None:
now = utils.now()
self.id: int
self.created = now
self.updated = now
self.name = ""
self.status = ""
self.hits = 0
self.triumph = 0
def get_name(self):
return self.name or "Nameless"
def get_age(self):
now = utils.now()
return utils.time_ago(self.created, now)
def describe(self):
print(f"Name is {self.get_name()}")
print(f"It hatched {self.get_age()}")
class Ants:
ants: list[Ant] = []
@staticmethod
def get_all() -> None:
Database.cursor.execute("SELECT id, created, updated, name, status, hits, triumph FROM ants")
rows = Database.cursor.fetchall()
ants = []
for row in rows:
ant = Ant()
ant.id = row[0]
ant.created = row[1]
ant.updated = row[2]
ant.name = row[3]
ant.status = row[4]
ant.hits = row[5]
ant.triumph = row[6]
ants.append(ant)
Database.connection.commit()
return ants
@staticmethod
def hatch() -> None:
now = utils.now()
Database.cursor.execute(
"INSERT INTO ants (created, updated) VALUES (?, ?)",
(now, now),
)
Database.connection.commit()
Database.cursor.execute("SELECT last_insert_rowid()")
row = Database.cursor.fetchone()
ant = Ant()
ant.id = row[0]
print(f"Ant hatched: {ant.id}")

21
database.py Normal file
View File

@ -0,0 +1,21 @@
from __future__ import annotations
import sqlite3
from pathlib import Path
class Database:
connection: sqlite3.Connection
cursor: sqlite3.Cursor
@staticmethod
def prepare() -> None:
Database.connection = sqlite3.connect("ants.db")
Database.cursor = Database.connection.cursor()
@staticmethod
def create() -> None:
with Path("schema.sql").open("r") as file:
schema = file.read()
Database.cursor.executescript(schema)
Database.connection.commit()

24
main.py Normal file
View File

@ -0,0 +1,24 @@
from __future__ import annotations
from database import Database
from window import Window
from ants import Ants
def main() -> None:
Database.prepare()
Database.create()
Ants.get_all()
for ant in Ants.ants:
ant.describe()
Window.make()
Window.add_buttons()
Window.add_view()
Window.start()
if __name__ == "__main__":
main()

1
requirements.txt Normal file
View File

@ -0,0 +1 @@
PySide6 == 6.7.2

1
run.sh Executable file
View File

@ -0,0 +1 @@
venv/bin/python main.py

22
schema.sql Normal file
View File

@ -0,0 +1,22 @@
CREATE TABLE IF NOT EXISTS ants (
-- Internal ID of the ant
id INTEGER PRIMARY KEY AUTOINCREMENT,
-- The date when the ant was created
created INTEGER NOT NULL DEFAULT 0,
-- The date when the ant was last changed
updated INTEGER NOT NULL DEFAULT 0,
-- The public name of the ant
name TEXT NOT NULL DEFAULT "",
-- The current text of the ant
status TEXT NOT NULL DEFAULT "",
-- The total number of hits taken
hits INTEGER NOT NULL DEFAULT 0,
-- The total number of triumph achieved
triumph INTEGER NOT NULL DEFAULT 0
);

49
utils.py Normal file
View File

@ -0,0 +1,49 @@
import time
def now() -> float:
return int(time.time())
def singular_or_plural(num: float, singular: str, plural: str) -> str:
if num == 1:
return singular
return plural
def time_ago(start_time: float, end_time: float) -> str:
diff = end_time - start_time
seconds = int(diff)
if seconds < 60:
word = singular_or_plural(seconds, "second", "seconds")
return f"{seconds} {word} ago"
minutes = seconds // 60
if minutes < 60:
word = singular_or_plural(minutes, "minute", "minutes")
return f"{minutes} {word} ago"
hours = minutes / 60
if hours < 24:
word = singular_or_plural(hours, "hour", "hours")
return f"{hours:.1f} {word} ago"
days = hours / 24
if days < 30:
word = singular_or_plural(days, "day", "days")
return f"{days:.1f} {word} ago"
months = days / 30
if months < 12:
word = singular_or_plural(months, "month", "months")
return f"{months:.1f} {word} ago"
years = months / 12
word = singular_or_plural(years, "year", "years")
return f"{years:.1f} {word} ago"

60
window.py Normal file
View File

@ -0,0 +1,60 @@
from __future__ import annotations
from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton, QHBoxLayout, QWidget
from PySide6.QtWidgets import QGraphicsView, QGraphicsScene, QVBoxLayout
from ants import Ants
class Window:
title = "Cromulant"
width = 800
height = 600
app: QApplication
window: QMainWindow
root: QWidget
@staticmethod
def make() -> None:
Window.app = QApplication([])
Window.window = QMainWindow()
Window.window.setWindowTitle(Window.title)
Window.window.resize(Window.width, Window.height)
Window.root = QWidget()
Window.window.setCentralWidget(Window.root)
@staticmethod
def add_buttons() -> None:
btn_hatch = QPushButton("Hatch Ant")
btn_terminate = QPushButton("Terminate")
btn_hatch.clicked.connect(Window.hatch)
btn_terminate.clicked.connect(Window.terminate)
layout = QHBoxLayout()
layout.addWidget(btn_hatch)
layout.addWidget(btn_terminate)
Window.root.setLayout(layout)
@staticmethod
def add_view() -> None:
Window.view = QGraphicsView()
Window.scene = QGraphicsScene()
Window.view.setScene(Window.scene)
layout = QVBoxLayout(Window.root)
layout.addWidget(Window.view)
@staticmethod
def hatch() -> None:
Ants.hatch()
@staticmethod
def terminate() -> None:
Ants.terminate()
@staticmethod
def start() -> None:
Window.window.show()
Window.app.exec()