Trying a date within Tkinter - Python - python

After testing out many times and reading Stackoverflow for several hours, I decided to right this question. My Text (part of the bigger code) is below:
import pandas as pd
import datetime as dt
from tkinter import *
import tkinter.filedialog
from tkinter import messagebox
def test_click():
global ipt_dt
global coef
global z
global w
z = item_prosp['Accrual_Start'].min()
w = item_prosp['Accrual_End'].max()
ipt_d = tkvar_d.get()
ipt_m = tkvar_m.get()
ipt_y = tkvar_y.get()
x = 0
while x == 0:
ipt = str(ipt_d + '/'+ ipt_m + '/' + ipt_y)
try:
ipt_dt = dt.datetime.strptime(ipt, "%d/%b/%Y")
if ipt_dt < z or ipt_dt > w:
messagebox.showinfo("Error", "The input date is outside scope date")
else:
print("Date ok")
x =+ 1
except:
messagebox.showerror("Error", "The input date is not valid")
ipt_d = 0
ipt_m = 0
ipt_y = 0
continue
And the tkinter section of the code that generate the inputs is:
#Question 1 - Evaluation date
label4 = Label(window, text='Please inform the valuation date :', bg='white').grid(row=13, column=0, columnspan=3, pady=2, sticky=W)
tkvar_d = StringVar(window)
tkvar_m = StringVar(window)
tkvar_y = StringVar(window)
choices_d = ['1', '2', '3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31']
choices_m = ['Jan', 'Feb', 'Mar','Apr','May','Jun','Jul','Aug','Sep','Oct', 'Nov', 'Dec']
choices_y = ['2018','2019', '2020', '2021','2022','2023','2024','2025','2026','2027','2028','2029','2030']
popupmenu_d = OptionMenu(window, tkvar_d, *choices_d)
popupmenu_m = OptionMenu(window, tkvar_m, *choices_m)
popupmenu_y = OptionMenu(window, tkvar_y, *choices_y)
label5 = Label(window, text='Day :', bg='white').grid(row=14, column=0, sticky=E+W)
popupmenu_d.grid(row=15, column=0, padx=2, sticky=E+W)
label6 = Label(window, text='Month :', bg='white').grid(row=14, column=1, sticky=E+W)
popupmenu_m.grid(row=15, column=1, padx=2, sticky=E+W)
label7 = Label(window, text='Year :', bg='white').grid(row=14, column=2, sticky=E+W)
popupmenu_y.grid(row=15, column=2, padx=2, sticky=E+W)
Button(window, text="Test Date", width=10, command=test_click).grid(row=15, column=3, padx=5, pady=10, sticky=W)
The sample value for W when the file is run is:
2018-04-18 00:00:00
and for Z is:
2018-04-18 00:00:00
My need is to import a file (externally built and already structured), read 2 values from it (variables Z and W in the code) and compare it with an input variable (ipt_dt) which is a date filled in by the user through 3 dropdown menus from tkinter.
The error is that the try is not going through the if statement and it never prints out if the input is outside the scope date. Everytime I enter a date smaller than the minimum date or higher than the maximum date it returns the showerror message eventhou it pritns the "Date ok".
Anyone has any idea on how to solve this or why my fi is being ignored?
Thanks!

I looked at your originally posted code and you load the Excel into a df with the load_click function. But you don't actually run the load_click function anywhere, so the dataframe isn't loaded and so z and w aren't filled.
If you change the click1() function as follows, then it should work (it did for me with some sample data).
def click1():
global a
a = tkinter.filedialog.askopenfilename(initialdir = "/",title = "Select file", filetypes = ( ("Excel file", "*.xlsx"), ("All files", "*.*") ) )
output1.insert(END, a)
global a1
a1 = output1.get()
load_click()
Or add a seperate 'load' button if you want (at the bottom of the #File1 part):
Button(window, text="Load", width=6, command=load_click).grid(row=4, column=3, padx=5, sticky=W)
You might also want to add another x = 1 in the if-statement. Otherwise the messagebox will keep popping up due to the while loop, making it impossible to correct the input date.
x = 0
while x == 0:
ipt = str(ipt_d + '/'+ ipt_m + '/' + ipt_y)
try:
ipt_dt = dt.datetime.strptime(ipt, "%d/%b/%Y")
print type(ipt_dt)
if (ipt_dt < z) or (ipt_dt > w):
messagebox.showinfo("Error", "The input date is outside scope date")
x = 1 # I've added this one
else:
print("Date ok")
x =+ 1
except:
messagebox.showerror("Error", "The input date is not valid")
ipt_d = 0
ipt_m = 0
ipt_y = 0
continue

Related

Values not stored in Tkinter Variables

In my code, I have tried to get the user input through text fields, store them in variables and finally print them in a tabular form.
The problem I am facing is that none of the values I enter through the text fields get displayed; when I try printing the variables, they come up empty.
Here's part of my code:
# SPASC
from tkinter import *
import tkinter as tk
import tkinter.ttk as tktrv
root = tk.Tk()
root.title("SPASC")
root.geometry("410x400")
lb1 = Label(root, text="SPASC \n Welcomes You !!!", fg="red", bg="sky blue"
, font=('Arial Black', 20), width=22, anchor=CENTER)
lb2 = Label(root, text="What would you like to compare?",
font=('Arial', 18), anchor=CENTER)
space1 = Label(root, text="\n\n")
lb1.grid(row=0)
lb2.grid(row=5)
space1.grid(row=1)
hpw, mil = StringVar(), StringVar()
def bt_cars():
w1 = Toplevel()
w1.title("Choose Features")
w1.geometry("430x200")
lb3 = Label(w1, text="Choose features for comparison", bg="yellow"
, font=('Arial Black', 18), width=25)
lb4 = Label(w1, text=" ", anchor=CENTER)
fr1 = LabelFrame(w1, width=20, padx=100)
hpw_cb = Checkbutton(fr1, text="Horsepower", variable=hpw, anchor='w', onvalue="Horsepower", offvalue="")
hpw_cb.grid()
hpw_cb.deselect()
mil_cb = Checkbutton(fr1, text="Mileage", variable=mil, anchor='w', onvalue="Mileage", offvalue="")
mil_cb.grid()
mil_cb.deselect()
var_stor = [hpw, mil]
print(hpw)
print(mil)
var_fill = []
for itr1 in var_stor:
if itr1 != "":
var_fill.append(itr1)
print(var_fill)
def car_1():
name1 = StringVar()
c1 = Toplevel()
c1.title("Car 1")
c1.geometry("430x200")
car1_lb1 = Label(c1, text="Car Name:")
name1_ifl = Entry(c1)
name1 = name1_ifl.get()
elm_var_fill = len(var_fill)
ct1 = 0
car1_val = []
for itr2 in var_fill:
if ct1 == elm_var_fill:
break
lb5 = Label(c1, text=itr2.get())
#Creating text field
ftr1_ifl = Entry(c1)
car1_ftr = ftr1_ifl.get()
car1_val.append(car1_ftr)
car1_ftr = None
lb5.grid(row=ct1 + 2, column=1)
ftr1_ifl.grid(row=ct1 + 2, column=2)
ct1 += 1
print(car1_val)
def display():
dp = Toplevel()
dp.title("Results")
dp.geometry("500x200")
car1_pt = 0
car2_pt = 0
car_tree = tktrv.Treeview(dp)
car_tree["columns"] = ("car1col")
car_tree.column("#0", width=120, minwidth=30)
car_tree.column("car1col", width=120, minwidth=30)
car_tree.heading("#0", text="Features" )
car_tree.heading("car1col", text=str(name1))
car_tree.pack()
c1.withdraw()
print(var_fill)
done1_bt = Button(c1, text="Continue", command=display)
name1_ifl.grid(row=0, column=2)
car1_lb1.grid(row=0, column=1)
done1_bt.grid(row=5,column=1)
w1.withdraw()
done_bt = Button(w1, text="Done", command=car_1)
done_bt.grid(row=3, column=1)
lb3.grid(row=0, column=1)
lb4.grid(row=1, column=1)
fr1.grid(row=2, column=1)
root.withdraw()
bt1 = Button(root, text="CARS", width=5, font=('Calibri', 15), command=bt_cars)
bt1.grid(row=7)
space2 = Label(root, text="\n\n")
space2.grid(row=6)
root.mainloop()
I am facing trouble with the variables named: hpw, mil, name1.
Any help would be welcome.
NOTE:- Please excuse the amount of code; I wanted others to replicate the error and see it for themselves
For the variables hpw and mil, these variables are empty strings that's why you are not getting any value from those checkboxes. To get values from the checkboxes replace these lines of code:
var_stor = [hpw, mil]
with
var_stor = [hpw_cb.cget('onvalue'), mil_cb.cget('onvalue')]
since you want the onvalue then you must use cget() method to access those values.
also, replace
lb5 = Label(c1, text=itr2.get())
with
lb5 = Label(c1, text=itr2)
because now you have required values (not objects) in a list, so just need to access those values.
For the variable name1 you can use #BokiX's method.
The problem is you are using get() wrong. You cannot use get() right after Entry() because as soon as entry is created it's getting the input before the user can even input something.
Use this code:
def get_input(text):
print(text)
e = Entry(root)
e.pack()
b = Button(root, text="Print input", command=lambda: get_input(e.get()))
b.pack()
Now get() method will not be executed before you click the button.

Variables not updating with Entry

Once again I am here asking for guidance with my crypto trading bot. This time, I am trying to update variables using Tkinter Entries. The default value for the Entry that I am trying to update is Crypto Symbol. I am trying to get a variable sym from this to use with the Binance API. I need to do sym = crypto.get()+'USDT' to get the variable that I need to plug into the command for the Trade button. For testing purposes, I set the command to print(sym) because I am trying to get it to update and that makes it easy to see what is going on. When I press the button, no matter what I have entered in the Entry, it always spits out Crypto SymboUSDT because Crypto Symbol is the original value, showing that what I am entering doesn't change anything. I will attach my code below, if you have a potential fix, please let me know :)
import pandas as pd
from pandas.core import frame, indexing
import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
import tkinter as tk
from tkinter import *
from tkinter.ttk import *
from tkinter import Entry, Tk, filedialog, Text
root = tk.Tk()
root.geometry('500x250')
root.title('Binance Bot')
# API Key Information
api_key = 'Censored'
api__secret = 'Censored'
# Entries
#Crypto Symbol
crypto = Entry(root, width=20, borderwidth=2, fg='gray')
crypto.insert(0, "Crypto Symbol")
def cryptoFocusIn(event):
crypto.config(foreground='black')
if crypto.get() == 'Crypto Symbol':
crypto.config(foreground='black')
crypto.delete(0, END)
def cryptoFocusOut(event):
if crypto.get() == '':
crypto.delete(0, END)
crypto.config(foreground='gray')
crypto.insert(0, 'Crypto Symbol')
crypto.bind('<FocusIn>', cryptoFocusIn)
crypto.bind('<FocusOut>', cryptoFocusOut)
crypto.pack()
sym = crypto.get()+'USDT'
# Order amount
OrderAmt = Entry(root, width=20, borderwidth=2, fg='gray')
OrderAmt.insert(0, "Order Amount (Coins)")
def AmtFocusIn(event):
OrderAmt.config(foreground='black')
if OrderAmt.get() == 'Order Amount (Coins)':
OrderAmt.config(foreground='black')
OrderAmt.delete(0, END)
def AmtFocusOut(event):
if OrderAmt.get() == '':
OrderAmt.delete(0, END)
OrderAmt.config(foreground='gray')
OrderAmt.insert(0, 'Order Amount (Coins)')
OrderAmt.bind('<FocusIn>', AmtFocusIn)
OrderAmt.bind('<FocusOut>', AmtFocusOut)
OrderAmt.pack()
qty = OrderAmt.get()
#Percentage drop for bot to buy
PercentDrop = Entry(root, width=20, borderwidth=2, fg='gray')
PercentDrop.insert(0, "% Drop to Buy")
def PDFocusIn(event):
PercentDrop.config(foreground='black')
if PercentDrop.get() == '% Drop to Buy':
PercentDrop.config(foreground='black')
PercentDrop.delete(0, END)
def PDFocusOut(event):
if PercentDrop.get() == '':
PercentDrop.delete(0, END)
PercentDrop.config(foreground='gray')
PercentDrop.insert(0, '% Drop to Buy')
PercentDrop.bind('<FocusIn>', PDFocusIn)
PercentDrop.bind('<FocusOut>', PDFocusOut)
PercentDrop.pack()
#Percent gain to Sell
PercentRaise = Entry(root, width=20, borderwidth=2, fg='gray')
PercentRaise.insert(0, "% Raise to Sell")
def PRFocusIn(event):
PercentRaise.config(foreground='black')
if PercentRaise.get() == '% Raise to Sell':
PercentRaise.config(foreground='black')
PercentRaise.delete(0, END)
def PRFocusOut(event):
if PercentRaise.get() == '':
PercentRaise.delete(0, END)
PercentRaise.config(foreground='gray')
PercentRaise.insert(0, '% Raise to Sell')
PercentRaise.bind('<FocusIn>', PRFocusIn)
PercentRaise.bind('<FocusOut>', PRFocusOut)
PercentRaise.pack()
# Percent bottom out to sell - Failsafe to not lose money
PercentBottom = Entry(root, width=20, borderwidth=2, fg='gray')
PercentBottom.insert(0, "% Drop Failsafe")
def PBFocusIn(event):
PercentBottom.config(foreground='black')
if PercentBottom.get() == '% Drop Failsafe':
PercentBottom.config(foreground='black')
PercentBottom.delete(0, END)
def PBFocusOut(event):
if PercentBottom.get() == '':
PercentBottom.delete(0, END)
PercentBottom.config(foreground='gray')
PercentBottom.insert(0, '% Drop Failsafe')
PercentBottom.bind('<FocusIn>', PBFocusIn)
PercentBottom.bind('<FocusOut>', PBFocusOut)
PercentBottom.pack()
# Get account information
client = Client(api_key, api__secret, tld='us')
#print(client.get_account())
# Datastream via websocket
def getMinuteData(symbol, interval, lookback):
frame = pd.DataFrame(client.get_historical_klines(symbol, interval, lookback+' min ago EST'))
frame = frame.iloc[:, :6]
frame.columns = ['Time', 'Open', 'High', 'Low', 'Close', 'Volume']
frame = frame.set_index('Time')
frame.index = pd.to_datetime(frame.index, unit='ms')
frame = frame.astype(float)
return frame
test = getMinuteData('BTCUSDT', '1m', '30')
# Trading Strategy - Buy if asset fell by more than 0.2% withint the last 30 min
# Sell if asset rises by more than 0.15% or falls further by 0.15%
def strategyTest(symbol, qty, entered=False):
df = getMinuteData(symbol, '1m', '30')
cumulRet = (df.Open.pct_change() + 1).cumprod() -1
if not entered:
if cumulRet [-1] < -0.002:
order = client.create_order(symbol=symbol, side='BUY', type = 'MARKET', quantity=qty)
print(order)
entered = True
else:
print("No trade executed")
if entered:
while True:
df = getMinuteData(symbol, '1m', '30')
sinceBuy = df.loc[df.index > pd.to_datetime(order['transactTime'], unit='ms')]
if len(sinceBuy) > 0:
sinceBuyReturns = (sinceBuy.Open.pct_change() + 1).cumprod() -1
if sinceBuyReturns[-1] > 0.0015 or sinceBuyReturns[-1] < -0.0015:
order = client.create_order(symbol=symbol, side='SELL', type = 'MARKET', quantity=qty)
print(order)
break
def confirm():
sym = crypto.get()+'USDT'
qty = OrderAmt.get()
# Buttons
Confirm = tk.Button(root, text='Confirm?', padx=10, pady=5, fg = 'white', bg = 'black', command = lambda: confirm() )
Confirm.pack()
#Trade = tk.Button(root, text='Trade', padx=10, pady=10, fg='white', bg='black', command = lambda: strategyTest(sym, qty) )
Trade = tk.Button(root, text='Trade', padx=10, pady=5, fg='white', bg='black', command = lambda: print(sym) )
Trade.pack()
root.mainloop()```

if a user enters a fraction as one of the values of the matrix that it will simply convert to float [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I want to fill in a matrix, and at the same time if a for example "1/7" get entered that it converts to float ? but it doesn't work
import fractions
import tkinter as tk
from tkinter import *
import numpy as np
import pandas as pd
from fractions import Fraction
from tkinter.font import Font
from PIL import Image, ImageTk
from PyQt5 import QtCore, QtGui, QtWidgets
import sqlite3
import tkinter.messagebox
import os
import sys
#this function contain a small window that you need to put the number of criteria in ,which will be the dimension of the maTRIX , WHEN I FILL THE matrix and click submit for it to be saved it doesn't work
def be():
window = Tk()
window.title("Dimensions ")
window.geometry("300x200")
def variable():
global fn, f
fn = entry_1.get()
f = entry_2.get()
ln = StringVar()
df = []
name = StringVar()
def save():
for entries in range(len(df)):
df[entries] = name.get()
for entries in range(len(df)):
df = df.append({'Critere': df[entries].get()}, ignore_index=True)
print(df)
df
def open_window():
root = tk.Tk()
root.geometry("460x600")
root.title('AHP Application ')
# global f
# f=printent()
# print(f)
for i in range(int(f)):
# c = input("Enter valeur {}: ".format(i))
my_label = Label(root, text="Entrer le critere numero 0{} :".format(i + 1), width=24, font=("bold", 10))
my_label.grid(row=i, column=0, pady=20, padx=5)
my_entry = Entry(root)
my_entry.grid(row=i, column=1, pady=20, padx=5)
df.append(my_entry)
suivant1 = tk.Button(root, text="Suivant", width=8, borderwidth=3, command=hope).place(x=370, y=40)
fermer2 = tk.Button(root, text="Fermer", width=8, borderwidth=3).place(x=370, y=90)
root.mainloop()
label_1 = Label(window, text="Entrer L'Objectif de Votre projet :", width=24, font=("bold", 10))
label_1.place(x=3, y=0)
entry_1 = Entry(window)
entry_1.place(x=100, y=30)
label_2 = Label(window, text="Entrer le nombre de critère :", width=20, font=("bold", 10))
label_2.place(x=3, y=70)
entry_2 = Entry(window)
# Remove default 0
entry_2.delete(0, END)
entry_2.place(x=100, y=100)
suivant = tk.Button(window, text="suivant", borderwidth=3, command=lambda: [variable(), open_window()]).place(x=40,
y=150)
fermer = tk.Button(window, text="fermer", borderwidth=3).place(x=190, y=150)
def hope():
win = Tk()
win.title("Matrix")
win.geometry("700x500")
global f
print(f)
wrapper1 = LabelFrame(win, text="Enter matrix")
wrapper3 = LabelFrame(win, text="Resultats")
wrapper1.pack(fill="both", expand="yes", padx=50, pady=20)
wrapper3.pack(fill="both", expand="yes", padx=20, pady=10)
def convert_to_float(frac_str):
try:
return float(frac_str)
except ValueError:
num, denom = frac_str.split('/')
try:
leading, num = num.split(' ')
whole = float(leading)
except ValueError:
whole = 0
frac = float(num) / float(denom)
return whole - frac if whole < 0 else whole + frac
# empty arrays for your Entrys and StringVars
text_var = []
entries = []
matrix = []
# callback function to get your StringVars
def get_mat():
for i in range(rows):
matrix.append([])
for j in range(cols):
matrix[i].append(convert_to_float (text_var[i][j].get()))
print(matrix)
b = np.array(matrix, dtype=float, order='C')
print(b)
global df2, df, c
index = []
columns = []
for i in range(int(f)):
index.append("critère{}".format(i + 1))
columns.append("critère{}".format(i + 1))
df = pd.DataFrame(data=b, index=index, columns=columns)
print(df)
arr = df.to_numpy()
global c
c = []
for i in range(len(df)):
c.append(np.prod(arr[i].astype(float)))
df2 = pd.DataFrame(data=c, index=range(int(f)), columns=["hi"])
print(df2)
# Label(win, text="Enter matrix :", font=('arial', 10, 'bold'),
# bg="bisque2").place(x=20, y=20)
x2 = 0
y2 = 0
rows = int(f)
cols = int(f)
global df2, df, c
x = np.array(['1.1', '2.2', '3.3'])
for i in range(rows):
# append an empty list to your two arrays
# so you can append to those later
text_var.append([])
entries.append([])
for j in range(cols):
# append your StringVar and Entry
text_var[i].append(StringVar())
entries[i].append(Entry(win, textvariable=text_var[i][j], width=5))
entries[i][j].place(x=80 + x2, y=30 + y2)
x2 += 40
y2 += 30
x2 = 0
button = Button(wrapper1, text="Submit", bg='bisque3', width=15, command=get_mat)
button.place(x=300, y=80)
my_label = Label(wrapper3, text="Lamda Max:", width=24, font=("bold", 10))
my_label.grid(row=0, column=0, pady=20, padx=5)
my_entry = Entry(wrapper3)
my_entry.grid(row=0, column=1, pady=20, padx=5)
# my_entry.insert(0,lamba)
my_label1 = Label(wrapper3, text="Indice de Coherence (CI):", width=24, font=("bold", 10))
my_label1.grid(row=1, column=0, pady=20, padx=5)
my_entry1 = Entry(wrapper3)
my_entry1.grid(row=1, column=1, pady=20, padx=5)
my_label2 = Label(wrapper3, text="Indice de Racio (IC):", width=24, font=("bold", 10))
my_label2.grid(row=2, column=0, pady=20, padx=5)
my_entry2 = Entry(wrapper3)
my_entry2.grid(row=2, column=1, pady=20, padx=5)
def calcule():
global f
df3 = pd.DataFrame(data=c, index=range(int(f)))
df3 = pow(df2, 1 / int(f))
print("df3 is ")
print(df3)
# Somme
Somme = df3.sum()
print("la somme est ")
print(Somme)
# weights
B = df3 / Somme
print(" La matrice des Poids:")
print(B)
# verify if somme of B is 1 , if it is then we are on the right road
Somm = B.sum()
print(Somm)
# consistency check
print("A3")
C = np.dot(df, B)
print(C)
# consistency check
print("A4")
D = C / B
print(D)
# global lamba
# Consistency Index
# lambda
lamba = np.mean(D)
print("the average is ")
print(lamba.to_string())
my_entry.insert(0, lamba.to_string(index=False))
# n = float(n)
CI = (lamba - float(f)) / (float(f) - 1)
print("The consistency Index is")
print(CI.to_string())
my_entry1.insert(0, CI.to_string(index=False))
# consistency ratio
if int(f) == 3:
RI = 0.52
elif int(f) == 4:
RI = 0.89
elif int(f) == 5:
RI = 1.11
elif int(f) == 6:
RI = 1.25
elif int(f) == 7:
RI = 1.35
elif int(f) == 8:
RI = 1.4
elif int(f) == 9:
RI = 1.45
elif int(f) == 10:
RI = 1.49
print("THE RATIO IS :")
print(RI)
CR = float(CI / RI)
my_entry2.insert(0, CR)
if CR < 0.1:
print("Congratulations ,Your criterias are consistent to go ahead \nThe value of consistency ratio is ",
CR,
"which is less han 0.1 ")
else:
print("you need to re-fill the matrix", CR)
button = Button(wrapper3, text="calcule", bg='bisque3', width=15, command=calcule)
button.place(x=500, y=100)
a = IntVar()
win.mainloop()
window.mainloop()
be()
Python actually has a built-in module just for this, which also has support for arbitrary-precision arithmetic and conversion to native floats.
>>> from fractions import Fraction
>>> frac = Fraction("1/7")
>>> float(fract)
0.14285714285714285
Easy to use, and works out-of-the-box. You can also convert it to an integer ratio, in case you want more accuracy than a native float can provide:
>>> frac.as_integer_ratio()
(1, 7)
The reason why float("1/7") doesn't work is because it's not a valid representation of an actual float: it's an integer ratio. Fractions, however, which provides native conversion to-and-from floats, does.

Python, Tkinter: Calculating days left with tkcalendar

I have two issues.
One:
I can't figure out how to calculate days left until a specific date which the user inputs in a calendar interface.
Secondly:
I want to use the numbers that the user has input in the interface to do some calculations with, and to watch what is going on I print some of the input to the terminal - however, the .value attribute returns "0" and I don't understand why.
Below the #PROXIMITY comment in the code you will find the calendar/date. I just want to subtract the date today from the date specified by the user in the calendar interface and output the days left.
Below the #VALUE is the calculation that prints "0" when i print the .value attribute.
Full code:
from tkcalendar import * # Calendar module
import tkinter.messagebox # Import the messagebox module
import datetime
import pickle
task_list = []
task_types = ['Sparetime', 'School', 'Work']
class Task:
def __init__(self, n, type_, i, m, p, h, v): #(w=8, p, u, n, v):
self.name = n
self.type = type_
self.impact = i
self.manageability = m
self.proximity = p
self.hours = h
self.value = v
#self.connectivity = c
##self.work = w ##hours of work per day
##self.urgency = u
##self.note = n
##self.value = v
def show_tasks():
# DELETED: for task in task_list:
# REPLACED WITH: task = task_list[-1]
task = task_list[-1]
#print(
#'Task:'+task.name + '\n' +
#'Impact:' + task.impact + '\n' +
#'Manageability:' + task.manageability + '\n' +
#'Hours:' + task.hours + '\n'
#'Value:' + task.value +'\n'
#)
print('Task:')
print(task.name)
print('\n')
print('Impact:')
print(task.impact)
print('\n')
print('manageability:')
print(task.manageability)
print('\n')
print('Hours')
print(task.hours)
print('\n')
print('Value:')
print(task.value)
def open_add_task():
taskwin = Toplevel(root)
taskwin.focus_force()
#TITLE
titlelabel = Label(taskwin, text='Title task concisely:', font=('Roboto',11,'bold')).grid(column=1, row=0)
name_entry = Entry(taskwin, width=40, justify='center')
name_entry.grid(column=1, row=1)
#TYPE
typelabel = Label(taskwin, text='Type', font=('Roboto',10)).grid(column=0, row=2)
type_var = StringVar(value=task_types[0])
OptionMenu(taskwin, type_var, *task_types).grid(column=0, row=3, sticky='nsew')
#IMPACT
impactlabel = Label(taskwin, text='Impact', font=('Roboto',10)).grid(column=1, row=2)
imp_var = StringVar(value=0)
OptionMenu(taskwin, imp_var, *range(0, 10+1)).grid(column=1, row=3, sticky='ns')
#MANAGEABILITY
manlabel = Label(taskwin, text='Manageability', font=('Roboto',10)).grid(column=2, row=2)
man_var = StringVar(value=0)
OptionMenu(taskwin, man_var, *range(0, 10+1)).grid(column=2, row=3, sticky='nsew')
#PROXIMITY
proximity_label = Label(taskwin, text = 'Choose a deadline', font=('Roboto',10), justify='center')
proximity_label.grid(column=1, row=4)
cal = Calendar(taskwin, selectmode='day', year=2021, month=4, day=27)
cal.grid(column=1, row=5)
def get_date():
proximity_output_date.config(text=cal.get_date()) ##the .config didn't work until i did .grid(column=, row=) on seperate lines
#HOURS(required)
hourlabel = Label(taskwin, text='Whole hours \n required', font=('Roboto',10)).grid(column=1, row=16)
hour_entry = Entry(taskwin, width=4, justify='center')
hour_entry.grid(column=1, row=17)
#CONNECTIVITY
#for index, task in enumerate(task_list):
#Checkbutton(taskwin, **options).grid(column=0, row=index)
C_lab = Label(taskwin,text="Check tasks this task is related to").grid(column=1, row=18)
placement=19
for task in task_list:
Checkbutton(taskwin, text=(task.name)).grid(column=1, row=placement, sticky="w")
placement+=1
#VALUE
val_var = (int(imp_var.get()))+ (int(man_var.get()))
def add_task():
if name_entry.get() != '': # If textbox inputfield is NOT empty do this:
task_list.append(Task(name_entry.get(), type_var.get(), imp_var.get(), man_var.get(), cal.get_date(), hour_entry.get(), val_var))
show_tasks()
listbox_tasks.insert(tkinter.END, name_entry.get())
name_entry.delete(0, tkinter.END)
taskwin.destroy()
else:
tkinter.messagebox.showwarning(title='Whoops', message='You must enter a task')
next_button = Button(taskwin, text='Next', font=('Roboto',10), command=add_task).grid(column=2, row=placement, sticky="e")
placement+=1
def sort_tasks():
pass
def delete_task():
try:
task_index = listbox_tasks.curselection()[0]
listbox_tasks.delete(task_index)
except:
tkinter.messagebox.showwarning(title='Error', message='You must select a task to delete')
def save_tasks():
pass
#tasks = listbox_tasks.get(0, listbox_tasks.size())
#pickle.dump(tasks, open('tasks.dat', 'wb'))
root = Tk()
task_frame = Frame()
# Create UI
your_tasks_label = Label(root, text='THESE ARE YOUR TASKS:', font=('Roboto',10, 'bold'), justify='center')
your_tasks_label.pack()
scrollbar_tasks = tkinter.Scrollbar(root)
scrollbar_tasks.pack(side=tkinter.RIGHT, fill=tkinter.Y)
listbox_tasks = tkinter.Listbox(root, height=10, width=50, font=('Roboto',10), justify='center') # tkinter.Listbox(where it should go, height=x, width=xx)
listbox_tasks.pack()
listbox_tasks.config(yscrollcommand=scrollbar_tasks.set)
scrollbar_tasks.config(command=listbox_tasks.yview)
try:
#tasks = pickle.load(open('tasks.dat', 'rb'))
listbox_tasks.delete(0, tkinter.END)
for task in task_list:
listbox_tasks.insert(tkinter.END, task)
except:
tkinter.messagebox.showwarning(title='Phew', message='You have no tasks')
#BUTTONS
Add_Button = Button(root, text='Add New', width=42, command=open_add_task)
Add_Button.pack()
button_delete_task = Button(root, text='Delete task', width=42, command=delete_task)
button_delete_task.pack()
button_save_tasks = Button(root, text='Save tasks', width=42, command=save_tasks)
button_save_tasks.pack()
#sort_type = StringVar(value='All')
#OptionMenu(btn_frame, sort_type, 'All', *task_types).grid(column=0, row=0, sticky='nsew')
#sort_imp = StringVar(value='Any')
#OptionMenu(btn_frame, sort_imp,'Any', *range(0, 10+1)).grid(column=1, row=0, sticky='nsew')
#Button(btn_frame, text='Sort', command=sort_tasks).grid(column=1, row=1, sticky='nsew')
root.mainloop()
how to calculate days left until a specific date
You might subtract datetime.date from datetime.date to get datetime.timedelta object holding numbers of days, consider following example
import datetime
d1 = datetime.date(2021, 1, 1) # year, month, day
d2 = datetime.date(2021, 1, 10)
diff21 = (d2-d1).days
diff12 = (d1-d2).days
print(diff21)
print(diff12)
output
9
-9
For getting current date you might use datetime.date.today().
For your first issue, you can use cal.selection_get() to return the selected date in datetime.date type. Then you can calculate the days left easily:
selected = cal.selection_get()
delta = (selected - datetime.date.today()).days
status = "overdue" if delta <= 0 else f"{delta} days left"
print(f"{selected} ({status})")
For second issue, you need to move the line val_var = (int(imp_var.get()))+ (int(man_var.get())) into add_task() function:
def add_task():
if name_entry.get() != '':
val_var = int(imp_var.get()) + int(man_var.get())
...
else:
...
Note that you need to do some validations on the values returned by imp_var.get() and man_var.get() to avoid exception due to invalid values.

Tkinter - How to limit the space used by a Text?

I'm trying to create a factorial calculator GUI.
The program works fine, but the problem I'm having is that when there are too many numbers coming in from the output, the screen automatically increases in width. I've tried using tk.Text to create a limit to the size of the textbox and so the text continues to the next row when the columns are filled.
But when I had to input text in to the tk.Text it didn't work since the variable I used is being processed in the function that gets called when the button is pressed. I have tried googling this problem but I couldn't find anything, I did find some people explaining how to use variables that get created/processed inside of a function, but that didn't work so I think I have done something wrong in my code.
Note: I am using lambda to call my function (not sure if this is important or not).
TLDR: Text gets too long when too much information is outputted. tk.Text didn't work for me since I couldn't figure out how to use the variable that is created/processed inside of a function that is only called when the button is pressed.
Here is my entire code: https://pastebin.com/1MkdRjVE
Code for my function:
def start_calc():
output_array = ["placehold"]
start_text.set("Loading...")
i = 1
global e1
global e2
output_array.clear()
string = e1.get()
string2 = e2.get()
integr = int(string)
integr2 = int(string2)
if string == "":
error_message.set("Please enter correct numbers.")
elif string2 == "":
error_message.set("Please enter correct numbers.")
else:
while integr2 >= i:
calc = integr ** i
calcstr = (str(calc))
output_array.append(calcstr)
i += 1
start_text.set("Start!")
output_array_str = (', '.join(output_array))
output_msg.set("Output: " + output_array_str)
print(output_array_str) #This is just so I know if it's working or not in the terminal
Code for my output:
output_msg = tk.StringVar()
output_text = tk.Label(root, textvariable=output_msg, font="Raleway")
output_msg.set("Output: ")
output_text.grid(columnspan=3, column=0, row=14)
I think this is what you are looking for:
#Imports
import tkinter as tk
#Variables
root = tk.Tk()
#Tkinter GUI setup basic
canvas = tk.Canvas(root, width= 400, height=400)
canvas.grid(columnspan=3, rowspan=120)
#Title
text = tk.Label(root, text="Calculating factorials", font="Raleway")
text.grid(column=1, row=1)
#Function
def start_calc():
output_array = ["", ""]
start_text.set("Loading...")
i = 1
global e1
global e2
output_array.clear()
string = e1.get()
string2 = e2.get()
integr = int(string)
integr2 = int(string2)
if string == "":
error_message.set("Please enter correct numbers.")
elif string2 == "":
error_message.set("Please enter correct numbers.")
else:
while integr2 >= i:
calc = integr ** i
calcstr = (str(calc))
output_array.append(calcstr)
i += 1
start_text.set("Start!")
output_array_str = (', '.join(output_array))
# Change the output
output_text.config(state="normal")
# delete last output:
output_text.delete("0.0", "end")
# insert new output:
output_text.insert("end", output_array_str)
output_text.config(state="disabled")
print(output_array_str) #This is just so I know if it's working or not in the terminal
#input
tk.Label(root, text="Number :").grid(row=10)
tk.Label(root, text="Factorial :").grid(row=11)
e1 = tk.Entry(root)
e2 = tk.Entry(root)
e1.grid(row=10, column=1)
e2.grid(row=11, column=1)
#Error message if the input is invalid
error_message = tk.StringVar()
error_text = tk.Label(root, textvariable=error_message, font="Raleway")
error_message.set(" ")
error_text.grid(column=1, row=12)
#Startbutton
start_text = tk.StringVar()
start_btn = tk.Button(root, textvariable=start_text, command=start_calc, font="Raleway", bg="#20bebe", fg="white", height=2, width=15)
start_text.set("Start!")
start_btn.grid(column=1, row=13, pady=10)
#output
output_text = tk.Text(root, height=1, width=20, wrap="none", font="Raleway")
output_text.insert("end", "Output")
output_text.config(state="disabled")
output_text.grid(columnspan=3, column=0, row=14, sticky="news")
#Adding a scrollbar
scrollbar = tk.Scrollbar(root, orient="horizontal", command=output_text.xview)
scrollbar.grid(columnspan=3, column=0, row=15, sticky="news")
output_text.config(xscrollcommand=scrollbar.set)
#disclaimer message
disclaimer_text = tk.Label(root, text="Disclaimer: The factorials will be printed from 1 to the number you entered.")
disclaimer_text.grid(columnspan=3, column=0, row=110)
root.mainloop()
I used a <tkinter.Text> widget with wrap="none", height=1 and width=20 to make the output box. I disabled the entry so that the user can't change the results but can still copy it.

Categories

Resources