Search code examples
pythontkintermathcanvasequation

Creating 9 percentages to add up to 100, seperate numbers with 2 digit decimals. Select largest number and set to middle dial


from tkinter import *
import tkinter as tk
import random
import os
from PIL import ImageTk, Image

window = tk.Tk()
window.geometry('800x900')
window.title("Time Teller App")
window.config(bg='gray')
window.resizable(False, False)

current_directory = os.getcwd()
folder1 = 'data'
os.chdir(os.path.join(current_directory, folder1))


def generate_percentages():
    percentages = [random.randint(1, 100) for _ in range(9)]
    total = sum(percentages)
    # Normalize the percentages so that they add up to 100
    percentages = [int(p/total*100) for p in percentages]
    # Sort the percentages in decreasing order
    percentages.sort(reverse=True)
    return percentages


def findAllOutcomes():
    percentages = generate_percentages()
    # Set the largest percentage as the middle text
    middleText = str(percentages[0]) + '%'
    # Set the other 8 percentages as the small texts
    smallTexts = [str(p) + '%' for p in percentages[1:]]
    # Make a grid?
    for vertical in range(3):
        # Increase vertical direction to make 3x3 grid
        for horizontal in range(3):
            gridPosx, gridPosy = (160, 190) #GRID POSITION
            distanceBetweenCellsX, distanceBetweenCellsY = (250, 250) #DISTANCE BETWEEN GRID CELLS
            
            x = horizontal * distanceBetweenCellsX + gridPosx
            y = vertical * distanceBetweenCellsY + gridPosy
            canvas.create_image(x, y, image=photo)
    
    # Create the middle dial
    canvas.create_text(400, 400, text=middleText, font=('Arial', 48, 'bold'), fill='white')
    
    # Create the other 8 small dials
    for i, text in enumerate(smallTexts):
        x = (i%3)*distanceBetweenCellsX + gridPosx
        y = (i//3)*distanceBetweenCellsY + gridPosy + 140
        canvas.create_text(x, y, text=text, font=('Arial', 28), fill='white')
    
    canvas.create_rectangle(295, 350, 505, 540, fill='gray', outline='gray')


canvas = Canvas(window, width=5000, height=5000)
canvas.config(bg='gray')
canvas.pack()

# Open and resize the image
image = Image.open('dial.png')
resized_image = image.resize((330, 196))

# Create the PhotoImage object from the resized image
photo = ImageTk.PhotoImage(resized_image)

findAllOutcomes()

window.mainloop()

Thats my code, I need the central dial to contain the largest number, and the smallest number on the last dial, these percentages need to all add up to 100, and use 2 digit decimals, preferably make these percentages in the center of the dial, and make the central dial (which i covered up) to just be a larger dial. Thanks! I'll post the image so you can test around. Image to download, PNG of dial(Lol, I screenshotted it from ookla speedtest)


Solution

  • You can simplify the logic as below:

    • get the sorted percentage list
    • move the largest number (first item) to the middle of the list
    • draw the image and the percentage text in one go using small font
    • update the middle percentage text to using larger font

    Below is the updated findAllOutcomes():

    def findAllOutcomes():
        percentages = generate_percentages()
        texts = [str(p)+'%' for p in percentages]
        # move the largest number to the middle of the list
        texts = texts[1:5] + [texts[0]] + texts[5:]
        # Make a grid?
        gridPosx, gridPosy = (160, 190) #GRID POSITION
        distanceBetweenCellsX, distanceBetweenCellsY = (250, 250) #DISTANCE BETWEEN GRID CELLS
        for vertical in range(3):
            # Increase vertical direction to make 3x3 grid
            for horizontal in range(3):
                x = horizontal * distanceBetweenCellsX + gridPosx
                y = vertical * distanceBetweenCellsY + gridPosy
                canvas.create_image(x, y, image=photo, anchor="c")
                canvas.create_text(x, y, text=texts[vertical*3+horizontal], font=('Arial', 28),
                                   fill='white', anchor='c', tags=f"{vertical}_{horizontal}")
    
        # make the middle dial text bigger
        canvas.itemconfig("1_1", font=('Arial', 48, 'bold'))
    

    And the result:

    enter image description here