Skip to content
This repository has been archived by the owner on Jun 24, 2024. It is now read-only.

Commit

Permalink
refactor: modularize main file, create new directories for cleaner look
Browse files Browse the repository at this point in the history
  • Loading branch information
seesmof committed Dec 22, 2023
1 parent e982439 commit ad800fe
Show file tree
Hide file tree
Showing 4 changed files with 218 additions and 206 deletions.
207 changes: 3 additions & 204 deletions src/main.py
Original file line number Diff line number Diff line change
@@ -1,211 +1,10 @@
from math import ceil
from rich.console import Console
from rich.traceback import install
from customtkinter import *
from collections import defaultdict

from components.AlertPopup import AlertPopup
from util.main import *

install()
console = Console()


def countLines(data):
lines = data.split("\n")
lines = [line for line in lines if line != ""]
return lines, len(lines)


def countSymbols(lines):
res = 0
for line in lines:
symbolsInLine = 0
for char in line:
symbolsInLine += 1
res += symbolsInLine
return res


def countWords(lines):
res = 0
for line in lines:
wordsInLine = line.split(" ")
res += len(wordsInLine)
return res


def getPopularWords(lines):
words = defaultdict(int)
for line in lines:
wordsInLine = line.split(" ")
for word in wordsInLine:
if word not in {"", " ", ".", "!", "?", "-"}:
words[word] += 1
return words


def showPopularWords(text):
console.log(
f"Started calculating most popular words from a text with {len(text)} symbols..."
)

# TODO read below and implement
# have a new window open where we would have a scrollable frame
# in the scrollable frame we would write all our popular words
# we will write from a list of custom objects from a class, that would have a word and a count
# each object would have a string representation
# or we could actually even have a class that would wrap our words container and do all the operations on them, not sure yet

lines, _ = countLines(text)
mostPopularWords = getPopularWords(lines)
mostPopularWords = sorted(
mostPopularWords.items(), key=lambda x: x[1], reverse=True
)

resultsString = "Most popular words in a given text:\n"
for word in mostPopularWords:
resultsString += f" - {word[0]}: {word[1]}\n"
AlertPopup(resultsString)

console.log(f"Calculated {len(mostPopularWords)} most popular words")


def getCurrentMetrics(text) -> tuple[int, int, int, int]:
lines, linesCount = countLines(text)
symbolsCount = countSymbols(lines)
wordsCount = countWords(lines)
timeToRead = ceil(wordsCount / 200)

return lines, linesCount, symbolsCount, wordsCount, timeToRead


def updateMetrics(
text: str,
linesHeading: CTkLabel,
symbolsHeading: CTkLabel,
wordsHeading: CTkLabel,
timeHeading: CTkLabel,
) -> None:
(
_,
linesCount,
symbolsCount,
wordsCount,
timeToRead,
) = getCurrentMetrics(text)

linesHeading.configure(
text=f"Lines: {linesCount}" if linesCount else "No lines found"
)
symbolsHeading.configure(
text=f"Symbols: {symbolsCount}" if symbolsCount else "No symbols found"
)
wordsHeading.configure(
text=f"Words: {wordsCount}" if wordsCount else "No words found"
)
timeHeading.configure(
text=f"Time to read: {timeToRead} min" if timeToRead else "No words found"
)


def renderInputSection(root) -> tuple[CTkLabel, CTkTextbox]:
getTextHeading = CTkLabel(
root, text="Enter text you want to count words in", font=("Arial", 14, "bold")
)
getTextInput = CTkTextbox(root, width=360, height=150)

getTextHeading.place(x=0, y=0)
getTextInput.place(x=0, y=30)

return getTextHeading, getTextInput


def renderResultsSection(root) -> tuple[CTkLabel, CTkLabel, CTkLabel, CTkLabel]:
resultsHeading = CTkLabel(root, text="Text Results", font=("Arial", 14, "bold"))
resultsLines = CTkLabel(root, text="No lines found", font=("Arial", 13))
resultsSymbols = CTkLabel(root, text="No symbols found", font=("Arial", 13))
resultsWords = CTkLabel(root, text="No words found", font=("Arial", 13))
resultsReadingTime = CTkLabel(root, text="No words found", font=("Arial", 13))

resultsHeading.place(x=0, y=190)
resultsLines.place(x=0, y=215)
resultsSymbols.place(x=0, y=235)
resultsWords.place(x=0, y=255)
resultsReadingTime.place(x=0, y=275)

return (
resultsHeading,
resultsLines,
resultsSymbols,
resultsWords,
resultsReadingTime,
)


def renderButtonsSection(root) -> tuple[CTkLabel, CTkButton, CTkButton, CTkButton]:
interactWithTextHeading = CTkLabel(
root,
text="Text Interactions",
font=("Arial", 14, "bold"),
)
showMostPopularWordsButton = CTkButton(
root,
text="Show Popular Words",
font=("Arial", 12, "bold"),
)
loadTextFromFileButton = CTkButton(
root,
text="Load Text From File",
font=("Arial", 12, "bold"),
)
saveTextToFileButton = CTkButton(
root,
text="Save Text To File",
font=("Arial", 12, "bold"),
)

interactWithTextHeading.place(x=210, y=190)
showMostPopularWordsButton.place(x=210, y=220)
loadTextFromFileButton.place(x=210, y=260)
saveTextToFileButton.place(x=210, y=300)

return interactWithTextHeading, showMostPopularWordsButton, loadTextFromFileButton


def renderMainTab(root) -> None:
getTextHeading, getTextInput = renderInputSection(root)

(
resultsHeading,
resultsLines,
resultsSymbols,
resultsWords,
resultsReadingTime,
) = renderResultsSection(root)

(
interactWithTextHeading,
showMostPopularWordsButton,
loadTextFromFileButton,
) = renderButtonsSection(root)

showMostPopularWordsButton.configure(
command=lambda: showPopularWords(getTextInput.get("0.0", "end"))
)
loadTextFromFileButton.configure(
command=lambda: console.print("TODO: load text from file")
)
getTextInput.bind(
"<KeyRelease>",
lambda event: updateMetrics(
getTextInput.get("0.0", "end"),
resultsLines,
resultsSymbols,
resultsWords,
resultsReadingTime,
),
)

from util.utils import *
from ui.ui import *


def configureApp() -> CTk:
Expand Down
135 changes: 135 additions & 0 deletions src/ui/ui.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
from customtkinter import *
from rich.console import Console

console = Console()


from util.utils import getCurrentMetrics, showPopularWords


def updateMetrics(
text: str,
linesHeading: CTkLabel,
symbolsHeading: CTkLabel,
wordsHeading: CTkLabel,
timeHeading: CTkLabel,
) -> None:
(
_,
linesCount,
symbolsCount,
wordsCount,
timeToRead,
) = getCurrentMetrics(text)

linesHeading.configure(
text=f"Lines: {linesCount}" if linesCount else "No lines found"
)
symbolsHeading.configure(
text=f"Symbols: {symbolsCount}" if symbolsCount else "No symbols found"
)
wordsHeading.configure(
text=f"Words: {wordsCount}" if wordsCount else "No words found"
)
timeHeading.configure(
text=f"Time to read: {timeToRead} min" if timeToRead else "No words found"
)


def renderInputSection(root) -> tuple[CTkLabel, CTkTextbox]:
getTextHeading = CTkLabel(
root, text="Enter text you want to count words in", font=("Arial", 14, "bold")
)
getTextInput = CTkTextbox(root, width=360, height=150)

getTextHeading.place(x=0, y=0)
getTextInput.place(x=0, y=30)

return getTextHeading, getTextInput


def renderResultsSection(root) -> tuple[CTkLabel, CTkLabel, CTkLabel, CTkLabel]:
resultsHeading = CTkLabel(root, text="Text Results", font=("Arial", 14, "bold"))
resultsLines = CTkLabel(root, text="No lines found", font=("Arial", 13))
resultsSymbols = CTkLabel(root, text="No symbols found", font=("Arial", 13))
resultsWords = CTkLabel(root, text="No words found", font=("Arial", 13))
resultsReadingTime = CTkLabel(root, text="No words found", font=("Arial", 13))

resultsHeading.place(x=0, y=190)
resultsLines.place(x=0, y=215)
resultsSymbols.place(x=0, y=235)
resultsWords.place(x=0, y=255)
resultsReadingTime.place(x=0, y=275)

return (
resultsHeading,
resultsLines,
resultsSymbols,
resultsWords,
resultsReadingTime,
)


def renderButtonsSection(root) -> tuple[CTkLabel, CTkButton, CTkButton, CTkButton]:
interactWithTextHeading = CTkLabel(
root,
text="Text Interactions",
font=("Arial", 14, "bold"),
)
showMostPopularWordsButton = CTkButton(
root,
text="Show Popular Words",
font=("Arial", 12, "bold"),
)
loadTextFromFileButton = CTkButton(
root,
text="Load Text From File",
font=("Arial", 12, "bold"),
)
saveTextToFileButton = CTkButton(
root,
text="Save Text To File",
font=("Arial", 12, "bold"),
)

interactWithTextHeading.place(x=210, y=190)
showMostPopularWordsButton.place(x=210, y=220)
loadTextFromFileButton.place(x=210, y=260)
saveTextToFileButton.place(x=210, y=300)

return interactWithTextHeading, showMostPopularWordsButton, loadTextFromFileButton


def renderMainTab(root) -> None:
getTextHeading, getTextInput = renderInputSection(root)

(
resultsHeading,
resultsLines,
resultsSymbols,
resultsWords,
resultsReadingTime,
) = renderResultsSection(root)

(
interactWithTextHeading,
showMostPopularWordsButton,
loadTextFromFileButton,
) = renderButtonsSection(root)

showMostPopularWordsButton.configure(
command=lambda: showPopularWords(getTextInput.get("0.0", "end"))
)
loadTextFromFileButton.configure(
command=lambda: console.print("TODO: load text from file")
)
getTextInput.bind(
"<KeyRelease>",
lambda event: updateMetrics(
getTextInput.get("0.0", "end"),
resultsLines,
resultsSymbols,
resultsWords,
resultsReadingTime,
),
)
2 changes: 0 additions & 2 deletions src/util/main.py

This file was deleted.

Loading

0 comments on commit ad800fe

Please sign in to comment.