Trying to create date range filter in my pysimplegui table

first of all wishing all of you successful 2024 year! Im trying to create a date range sortable filter in my PySimpleGUI table app, but unfortunately im getting this error all the time:

Traceback (most recent call last):
  File "c:\Python\Lib\KW-APP-FINAL.py", line 285, in <module>
    filtered_td = filter_data(date_from, date_to, td)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "c:\Python\Lib\KW-APP-FINAL.py", line 46, in filter_data
    date = datetime.datetime.strptime(item['Дата'], '%Y-%m-%d %H:%M:%S').date()
                                      ~~~~^^^^^^^^
TypeError: list indices must be integers or slices, not str

So any ideas how to fix that? P.S. I'm newbie in Python, sorry :)

Here is the code:

`

def filter_data(date_from, date_to, td):
    filtered_td = []
    for item in td:
        date = datetime.datetime.strptime(item['Дата'], '%Y-%m-%d %H:%M:%S').date()
        if date_from <= date <= date_to:
            filtered_td.append(item)
    return filtered_td`

and also in the loop:

`

elif event == 'Покажи':
                date_from = values['-DATE_FROM-']
                date_to = values['-DATE_TO-']

                if date_from and date_to:
                    try:
                        date_from = datetime.datetime.strptime(date_from, '%Y-%m-%d %H:%M:%S').date()
                        date_to = datetime.datetime.strptime(date_to, '%Y-%m-%d %H:%M:%S').date()

                        filtered_td = filter_data(date_from, date_to, td)

                        window['-TABLE-'].update(values=filtered_td)
                    except ValueError:
                        sg.popup('Въвели сте неправилен формат на дата. Моля използвайте ГОДИНА-МЕСЕЦ-ДЕН!')
                else:
                    sg.popup('Моля въведете начална и крайна дата!')

`

Upvotes: 0

Views: 169

Answers (2)

Jason Yang
Jason Yang

Reputation: 13051

It is caused by that the item in td is a List and you want to index it by a string 'Дата'. Maybe it can be done by td[Headings.index('Дата')].

Example Code

from datetime import datetime
import PySimpleGUI as sg

def date(date):
    return datetime.strptime(date, '%m/%d/%Y')

information = [
    ['President',           'Born',       'Died',       'Age'],
    ['George Washington',   '02/22/1732', '12/14/1799', '67'],
    ['John Adams',          '10/30/1735', '07/04/1826', '90'],
    ['Thomas Jefferson',    '04/13/1743', '07/04/1826', '83'],
    ['James Madison',       '03/16/1751', '06/28/1836', '85'],
    ['James Monroe',        '04/28/1758', '07/04/1831', '73'],
    ['John Quincy Adams',   '07/11/1767', '02/23/1848', '80'],
    ['Andrew Jackson',      '03/15/1767', '06/08/1845', '78'],
    ['Martin Van Buren',    '12/05/1782', '07/24/1862', '79'],
    ['William Harrison',    '02/09/1773', '04/04/1841', '68'],
    ['John Tyler',          '03/29/1790', '01/18/1862', '71'],
    ['James Polk',          '11/02/1795', '06/15/1849', '53'],
    ['Zachary Taylor',      '11/24/1784', '07/09/1850', '65'],
    ['Millard Fillmore',    '01/07/1800', '03/08/1874', '74'],
    ['Franklin Pierce',     '11/23/1804', '10/08/1869', '64'],
    ['James Buchanan',      '04/23/1791', '06/01/1868', '77'],
    ['Abraham Lincoln',     '02/12/1809', '04/15/1865', '56'],
    ['Andrew Johnson',      '12/29/1808', '07/31/1875', '66'],
    ['Ulysses S. Grant',    '04/27/1822', '07/23/1885', '63'],
    ['Rutherford B. Hayes', '10/04/1822', '01/17/1893', '70'],
    ['James Garfield',      '11/19/1831', '09/19/1881', '49'],
    ['Chester A. Arthur',   '10/05/1829', '11/18/1886', '56'],
    ['Grover Cleveland',    '03/18/1837', '06/24/1908', '71'],
    ['Benjamin Harrison',   '08/20/1833', '03/13/1901', '67'],
    ['Grover Cleveland',    '03/18/1837', '06/24/1908', '71'],
    ['William McKinley',    '01/29/1843', '09/14/1901', '58'],
    ['Theodore Roosevelt',  '10/27/1858', '01/06/1919', '60'],
    ['William Taft',        '09/15/1857', '03/08/1930', '72'],
    ['Woodrow Wilson',      '12/28/1856', '02/03/1924', '67'],
    ['Warren Harding',      '11/02/1865', '08/02/1923', '57'],
    ['Calvin Coolidge',     '07/04/1872', '01/05/1933', '60'],
    ['Herbert Hoover',      '08/10/1874', '10/20/1964', '90'],
    ['Franklin Roosevelt',  '01/30/1882', '04/12/1945', '63'],
    ['Harry Truman',        '05/08/1884', '12/26/1972', '88'],
    ['Dwight Eisenhower',   '10/14/1890', '03/28/1969', '78'],
    ['John F. Kennedy',     '05/29/1917', '11/22/1963', '46'],
    ['Lyndon Johnson',      '08/27/1908', '01/22/1973', '64'],
    ['Richard Nixon',       '01/09/1913', '04/22/1994', '81'],
    ['Gerald Ford',         '07/14/1913', '12/20/2006', '93'],
    ['Ronald Reagan',       '02/06/1911', '06/05/2004', '93'],
    ['George H.W. Bush',    '06/12/1924', '11/30/2018', '94'],
]

headings = information[0]
data = information[1:]
widths = list(map(max, map(lambda x: map(lambda y:len(str(y))+2, x), zip(*information))))

sg.set_options(font=("Courier New", 12))
layout = [
    [sg.Text("Date (M/D/Y) From"),
     sg.Input(size=10, key="DATE_FM"),
     sg.Text("To"),
     sg.Input(size=10, key="DATE_TO"),
     sg.Button("Filter", expand_x=True)],
    [sg.Table(
        data,
        headings=headings,
        auto_size_columns=False,
        col_widths=widths,
        cols_justification='lccc',
        key='TABLE')],
    [sg.Text("", relief=sg.RELIEF_SUNKEN, expand_x=True, key='STATUS')],
]
window = sg.Window("Table", layout, margins=(0, 0))

while True:

    event, values = window.read()

    if event == sg.WINDOW_CLOSED:
        break

    elif event == "Filter":
        try:
            window['STATUS'].update("")
            date_from = date(values["DATE_FM"])
            date_to   = date(values["DATE_TO"])
        except ValueError:
            window['STATUS'].update("Wrong date !!!")
            continue
        """
        data = [
            [name, born, died, age]
                for name, born, died, age in information[1:]
                    if date_from <= date(born) <= date_to
        ]
        """
        data = [item for item in information[1:] if date_from <= date(item[headings.index("Born")]) <= date_to]
        window['TABLE'].update(data)

window.close()

enter image description here


You can refer following code about how to revise your code to work.

from pprint import pprint
from datetime import datetime

def string_date(date):
    return datetime.strptime(date, '%d.%m.%Y')

td = [['1', 'Владимир Костов', '0877050292', '[email protected]', 'София', 'бул. Андрей Ляпчев 72', 'Младост 2', '1784', 'Google', 'Kashmir Silk Exclusive', '515225', '240x170', '11599', '65%', '1', 'Брой', 'Брой 10000, Карта 1599', '17.11.2023'],]
Headings=['№: на гаранция', 'Име и фамилия', 'Телефонен номер', 'Имейл', 'Град/село', 'Улица', 'Квартал', 'Пощенски код', 'Как разбрахте за нас?', 'Име на килим', 'Код на килим', 'Размер на килим', 'Цена на килим', 'Процент отстъпка', 'Брой килими', 'Начин на плащане', 'Коментар', 'Дата']

# Initial value to run this script
values = {'-DATE_FROM-':"01.11.2023", '-DATE_TO-':"01.12.2023"}

date_from   = string_date(values['-DATE_FROM-'])
date_to     = string_date(values['-DATE_TO-'])

filtered_td = []
column = Headings.index('Дата')
for item in td:
    date = string_date(item[column])  # .date()
    if date_from <= date <= date_to:
        filtered_td.append(item)

pprint(filtered_td)
[['1',
  'Владимир Костов',
  '0877050292',
  '[email protected]',
  'София',
  'бул. Андрей Ляпчев 72',
  'Младост 2',
  '1784',
  'Google',
  'Kashmir Silk Exclusive',
  '515225',
  '240x170',
  '11599',
  '65%',
  '1',
  'Брой',
  'Брой 10000, Карта 1599',
  '17.11.2023']]

Upvotes: 0

td=[['1', 'Владимир Костов', '0877050292', '[email protected]', 'София', 'бул. Андрей Ляпчев 72', 'Младост 2', '1784', 'Google', 'Kashmir Silk Exclusive', '515225', '240x170', '11599', '65%', '1', 'Брой', 'Брой 10000, Карта 1599', '17.11.2023']]
Headings=['№: на гаранция', 'Име и фамилия', 'Телефонен номер', 'Имейл', 'Град/село', 'Улица', 'Квартал', 'Пощенски код', 'Как разбрахте за нас?', 'Име на килим', 'Код на килим', 'Размер на килим', 'Цена на килим', 'Процент отстъпка', 'Брой килими', 'Начин на плащане', 'Коментар', 'Дата']

def filter_data(date_from, date_to, td):
filtered_td = []
for values in td:
    date = datetime.datetime.strptime(values['Дата'], '%Y-%m-%d %H:%M:%S').date()
    if date_from <= date <= date_to:
        filtered_td.append(values)
return filtered_td

And this is about the first problem...

... then i have this

            elif event == 'Покажи':
            date_from = values['-DATE_FROM-']
            date_to = values['-DATE_TO-']

            if date_from and date_to:
                try:
                    date_from = datetime.datetime.strptime(date_from, '%Y-%m-%d %H:%M:%S').date()
                    date_to = datetime.datetime.strptime(date_to, '%Y-%m-%d %H:%M:%S').date()

                    filtered_td = filter_data(date_from, date_to, td)

                    window['-TABLE-'].update(values=filtered_td)
                except ValueError:
                    sg.popup('Въвели сте неправилен формат на дата. Моля използвайте ГОДИНА-МЕСЕЦ-ДЕН!')
            else:
                sg.popup('Моля въведете начална и крайна дата!')

And the following error:

> Traceback (most recent call last):   File
> "c:\Python\Lib\KW-APP-FINAL.py", line 328, in <module>
>     filtered_value = filter_data(date_from, date_to, td)
>                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   File "c:\Python\Lib\KW-APP-FINAL.py", line 43, in filter_data
>     date = datetime.datetime.strptime(values['Дата'], '%Y-%m-%d %H:%M:%S').date()
>                                       ~~~~~~^^^^^^^^ TypeError: list indices must be integers or slices, not str

P.S. Im very, very sorry if its easy, but i cannot figure it out, so if possible provide "instead of your code" please... :)

BIG THANKS!

Upvotes: 0

Related Questions