├── .idea ├── .gitignore ├── vcs.xml ├── misc.xml ├── inspectionProfiles │ └── profiles_settings.xml ├── modules.xml └── Custom Widgets for CTk.iml ├── CTkDataVisualizingWidgets ├── __init__.py ├── ctk_graph.py ├── ctk_chart.py └── ctk_calender.py └── README.md /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /CTkDataVisualizingWidgets/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | CTkDataVisualizingWidgets 3 | """ 4 | 5 | from .ctk_calender import CTkCalendar 6 | from .ctk_graph import CTkGraph 7 | from .ctk_chart import CTkChart 8 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/Custom Widgets for CTk.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CTkDataVisualizingWidgets 2 | **Custom data visualizing widgets like calendar, graph and chart.** 3 | 4 | ## CTkCalendar 5 | A calendar widget consists of two parts title_bar and calendar frame. You can customize virtually everything in the widget. There is 6 | also an option to define the current day, if you define today_fg_color 7 | 8 | Basic view on the left and with little customization on the right: 9 | 10 | ![image](https://github.com/ZikPin/Custom-widgets-for-CTk/assets/65452275/b27c41e8-c5bb-4788-92ad-f1e39bc6ab49) 11 | 12 | To use just init the class and pass the `parent` (the only required argument). The parameters starting with title_bar are responsible for 13 | widgets inside the title bar and the ones starting with the calendar are responsible for the frame where the calendar is displayed 14 | 15 | Creating the customized widget on the preview: 16 | ```python 17 | from CTkDataVisualizingWidgets import * 18 | import customtkinter as ctk 19 | 20 | window = ctk.CTk() 21 | window.title("Calendar Widget") 22 | ctk.set_appearance_mode("dark") 23 | 24 | # init calendar 25 | calendar_widget = CTkCalendar(window, width=300, height=210, border_width=3, border_color="white", 26 | fg_color="#020317", title_bar_border_width=3, title_bar_border_color="white", 27 | title_bar_fg_color="#020F43", calendar_fg_color="#020F43", corner_radius=30, 28 | title_bar_corner_radius=10, calendar_corner_radius=10, calendar_border_color="white", 29 | calendar_border_width=3, calendar_label_pad=5, 30 | today_fg_color="white", today_text_color="black") 31 | calendar_widget.pack(side="left", padx=20) 32 | 33 | window.mainloop() 34 | ``` 35 | 36 | ## CTkGraph 37 | The graph widgets lets you visualize the list of integer values as a graph. You can customize almost every part, except for corner radius of canvas (where the graph is drawn). You can also set a custom title and define its family, size and color. If you do not define a title 38 | the widget will display only the graph 39 | 40 | Default view on left and with customization on the right: 41 | 42 | ![image](https://github.com/ZikPin/Custom-widgets-for-CTk/assets/65452275/17b46820-d881-4f27-8ea9-7dd572d9d704) 43 | 44 | To use just define parent and supply with list of integers. Example code: 45 | ```python 46 | from CTkDataVisualizingWidgets import * 47 | import customtkinter as ctk 48 | 49 | window = ctk.CTk() 50 | window.title("Calendar Widget") 51 | ctk.set_appearance_mode("dark") 52 | 53 | values = [49, 76, 61, 65, 51, 24, 9, 29, 53, 24] 54 | 55 | CTkGraph(window, values, width=250, height=200, fg_color="#FF7761", graph_color="#FF7761", 56 | graph_fg_color="#FF5330", title="Screentime", title_font_size=30, corner_radius=20).pack(side="left", padx=20, pady=20) 57 | 58 | window.mainloop() 59 | ``` 60 | ## CTkChart 61 | This is widget to create a chart representation of a dict[str, int]. It takes str of the dict as a key and a title 62 | for certain stat and int or float for that matter as the value and draws it on the canvas. There are also 63 | indicators like average and max value. 64 | 65 | You can also set title, if you do not define it, it wont be rendered. 66 | 67 | There are two values with tuple[bool, bool] format: 68 | - stat_info_show: first bool is responsible for drawing the value in the stat, second for drawing title 69 | - show_indicators: first bool is responsible for max value, second for average. 70 | 71 | Default view on the left and with customization on the right: 72 | 73 | ![image](https://github.com/ZikPin/Custom-widgets-for-CTk/assets/65452275/e40ea973-77d0-42c4-b740-535c15ad5748) 74 | 75 | Example code to create the widget: 76 | 77 | ```python 78 | from CTkDataVisualizingWidgets import * 79 | import customtkinter as ctk 80 | 81 | window = ctk.CTk() 82 | window.title("Calendar Widget") 83 | ctk.set_appearance_mode("dark") 84 | 85 | value = {'JJ': 5, 'OO': 0, 'WW': 7, 'TT': 3, 'GG': 15, 'FF': 10, 'HH': 1, 'PP': 12, "AA": 4} 86 | CTkChart(window, value, corner_radius=20, fg_color="#032680", stat_color="#1D6FFF", chart_fg_color="#032680", 87 | show_indicators=(False, True), stat_info_show=(False, True), chart_arrow="none", border_width=2, 88 | border_color="white", indicator_line_color="#1942AC", indicator_text_color="#020F43", stat_width=15, 89 | stat_title_color="#1D6FFF", chart_axis_width=3, width=300, height=200).pack(side="left", pady=20, padx=20) 90 | 91 | window.mainloop() 92 | ``` 93 | -------------------------------------------------------------------------------- /CTkDataVisualizingWidgets/ctk_graph.py: -------------------------------------------------------------------------------- 1 | import customtkinter as ctk 2 | from datetime import datetime 3 | import tkinter as tk 4 | 5 | class CTkGraph(ctk.CTkFrame): 6 | """ 7 | Widget to display list of integers as a graph. You can customize almost everything, except for the corner radius 8 | of the canvas that draws the graph. 9 | 10 | You can also set a custom title, if you don't do is the Labeled won't be rendered. 11 | 12 | Graph axis vars are responsible for the arrows of the graph, graph line is responsible for the outline of the 13 | graph polygon (the graph is represented with a polygon) 14 | """ 15 | def __init__(self, master, 16 | data_values: list, 17 | fg_color="gray17", 18 | graph_fg_color="gray17", 19 | width=200, 20 | height=200, 21 | border_width=None, 22 | border_color=None, 23 | corner_radius=None, 24 | graph_color="gray20", 25 | graph_axis_width=3, 26 | graph_line_width=2, 27 | graph_axis_color="white", 28 | graph_line_color="white", 29 | graph_axis_arrow="last", 30 | title_font_family="Arial", 31 | title_font_size=16, 32 | title_text_color=None, 33 | title=None): 34 | 35 | super().__init__(master=master, fg_color=fg_color, width=width, height=height, corner_radius=corner_radius, 36 | border_color=border_color, border_width=border_width) 37 | 38 | # data 39 | self.data_values = data_values 40 | self.date = self.current_date() 41 | self.date_display = self.date[:] 42 | self.graph_fg_color = graph_fg_color 43 | self.graph_color = graph_color 44 | self.main_canvas = None 45 | 46 | # graph data 47 | self.width = width 48 | self.height = height 49 | self.graph_axis_width = graph_axis_width 50 | self.graph_line_width = graph_line_width 51 | self.graph_axis_color = graph_axis_color 52 | self.graph_line_color = graph_line_color 53 | self.graph_axis_arrow = graph_axis_arrow 54 | 55 | # title data 56 | self.title_font_family = title_font_family 57 | self.title_font_size = title_font_size 58 | self.title_text_color = title_text_color 59 | self.title = title 60 | 61 | # setting up 62 | self.setup_stat() 63 | 64 | def setup_stat(self): 65 | if self.title is not None: 66 | ctk.CTkLabel(self, text=self.title, text_color=self.title_text_color, 67 | font=ctk.CTkFont(self.title_font_family, self.title_font_size)).pack(fill="x", padx=10, pady=10) 68 | 69 | self.main_canvas = ctk.CTkCanvas(self, background=self.graph_fg_color, bd=0, highlightthickness=0, 70 | relief="ridge", width=self.width, height=self.height) 71 | 72 | self.main_canvas.pack(expand=True, fill="both", padx=self._corner_radius//2, pady=self._corner_radius//2) 73 | 74 | self.main_canvas.bind("", lambda event: self.draw_stats(event.width, event.height)) 75 | 76 | def draw_stats(self, width, height): 77 | # drawing graph lines 78 | self.main_canvas.delete("all") 79 | 80 | # axis for the graph 81 | self.main_canvas.create_line(width * 0.05, height * 0.95, width * 0.05, height * 0.05, fill=self.graph_axis_color, 82 | width=self.graph_axis_width, arrow=self.graph_axis_arrow) 83 | self.main_canvas.create_line(width * 0.05, height * 0.95, width * 0.95, height * 0.95, fill=self.graph_axis_color, 84 | width=self.graph_axis_width, arrow=self.graph_axis_arrow) 85 | 86 | data_len = len(self.data_values) 87 | max_value = max(self.data_values) 88 | gap = (width - 15) // data_len 89 | coordinates = [(width * 0.05, height * 0.95)] 90 | 91 | for i in range(data_len): 92 | h = height * 0.8 * self.data_values[i] / max_value 93 | coordinates.append((width * 0.05 + gap * i, height * 0.95 - h)) 94 | 95 | else: 96 | coordinates.append((width * 0.05 + gap * data_len - gap, height * 0.95)) 97 | 98 | self.main_canvas.create_polygon(coordinates, width=self.graph_line_width, fill=self.graph_color, 99 | outline=self.graph_line_color) 100 | 101 | def current_date(self) -> tuple[int, int, int]: 102 | date = str(datetime.now()).split() 103 | year, month, day = date[0].split("-") 104 | return int(day), int(month), int(year) 105 | -------------------------------------------------------------------------------- /CTkDataVisualizingWidgets/ctk_chart.py: -------------------------------------------------------------------------------- 1 | import customtkinter as ctk 2 | import tkinter as tk 3 | 4 | class CTkChart(ctk.CTkFrame): 5 | """ 6 | This is widget to create a chart representation of a dict[str, int]. It takes str of the dict as a key and a title 7 | for certain stat and int or float for that matter as the value and draws it on the canvas. There are also 8 | indicators like average and max value. 9 | 10 | You can also set title, if you do not define it, it wont be rendered. 11 | 12 | There are two values with tuple[bool, bool] format: 13 | * stat_info_show: first bool is responsible for drawing the value in the stat, second for drawing title 14 | * show_indicators: first bool is responsible for max value, second for average. 15 | """ 16 | def __init__(self, master, 17 | data: dict, 18 | width=350, 19 | height=250, 20 | fg_color="gray17", 21 | corner_radius=5, 22 | border_width=None, 23 | border_color=None, 24 | chart_fg_color="gray17", 25 | title=None, 26 | title_font_family="Arial", 27 | title_text_color="white", 28 | title_font_size=16, 29 | chart_axis_width=4, 30 | chart_axis_color="white", 31 | chart_arrow="last", 32 | show_indicators: tuple[bool, bool] = (True, True), 33 | indicator_line_color="white", 34 | indicator_text_color="white", 35 | stat_color="white", 36 | stat_width=30, 37 | stat_info_show: tuple[bool, bool] = (True, True), 38 | stat_text_color="gray17", 39 | stat_title_color="white"): 40 | super().__init__(master=master, fg_color=fg_color, corner_radius=corner_radius, border_color=border_color, 41 | border_width=border_width, width=width, height=height) 42 | 43 | # data 44 | self.data = data 45 | self.data_avg, self.data_max = self.format_data() 46 | 47 | # data about chart axis 48 | self.chart_axis_width = chart_axis_width 49 | self.chart_axis_color = chart_axis_color 50 | self.chart_arrow = chart_arrow 51 | 52 | # data about indicators 53 | self.show_indicators: tuple[bool, bool] = show_indicators 54 | self.indicator_line_color = indicator_line_color 55 | self.indicator_text_color = indicator_text_color 56 | 57 | # data about stats 58 | self.stat_color = stat_color 59 | self.stat_width = stat_width 60 | self.stat_info_show = stat_info_show 61 | self.stat_text_color = stat_text_color 62 | self.stat_title_color = stat_title_color 63 | 64 | self.main_canvas = ctk.CTkCanvas(self, background=chart_fg_color, bd=0, highlightthickness=0, relief="ridge", 65 | width=width, height=height) 66 | 67 | if title is not None: 68 | ctk.CTkLabel(self, text=title, font=ctk.CTkFont(title_font_family, title_font_size, "bold"), 69 | text_color=title_text_color).pack(fill="x", expand=True) 70 | 71 | self.main_canvas.pack(expand=True, fill="both", padx=corner_radius//1.5, pady=corner_radius//1.5) 72 | self.main_canvas.bind("", lambda event: self.draw_stats()) 73 | 74 | def format_data(self) -> tuple[float, int]: 75 | m = 0.01 76 | s, count = 0, 0.01 77 | 78 | for value in self.data.values(): 79 | s += value 80 | count += 1 81 | m = max(m, value) 82 | 83 | return s/count, m 84 | 85 | def draw_stats(self): 86 | # updating canvas and canvas info 87 | self.main_canvas.delete("all") 88 | canvas_height = self.main_canvas.winfo_height() 89 | canvas_width = self.main_canvas.winfo_width() 90 | 91 | # drawing graph axis 92 | self.main_canvas.create_line(0+self.chart_axis_width, canvas_height-self.chart_axis_width-canvas_height*0.15, 93 | canvas_width, canvas_height-self.chart_axis_width-canvas_height*0.15, 94 | capstyle="round", width=self.chart_axis_width, fill=self.chart_axis_color, 95 | arrow=self.chart_arrow) 96 | self.main_canvas.create_line(0 + self.chart_axis_width, canvas_height-self.chart_axis_width-canvas_height*0.15, 97 | 0 + self.chart_axis_width, 0, arrow=self.chart_arrow, 98 | capstyle="round", width=self.chart_axis_width, fill=self.chart_axis_color) 99 | 100 | for index, key in enumerate(self.data.keys()): 101 | self.draw_stat_day(canvas_width*0.01, canvas_height * 0.2, canvas_width * 0.9, canvas_height * 0.55, 102 | index, key) 103 | 104 | # drawing indicator lines 105 | if self.show_indicators[0]: 106 | self.draw_stat_indicator(canvas_width * 0.9, canvas_height * 0.2 - 15, "max") 107 | if self.show_indicators[1]: 108 | avg_height = canvas_height * 0.55 - canvas_height * 0.55 * (self.data_avg / self.data_max) 109 | self.draw_stat_indicator(canvas_width * 0.9, avg_height + canvas_height * 0.2, "avg") 110 | 111 | def draw_stat_day(self, graph_x_offset, graph_y_offset, graph_width, graph_height, index, key): 112 | day_width = graph_width//len(self.data.keys()) 113 | day_offset = day_width*0.6 114 | 115 | value = self.data[key] 116 | day_stat_height = value / self.data_max * graph_height 117 | 118 | self.main_canvas.create_line(graph_x_offset + day_width * index + day_offset, 119 | graph_y_offset + graph_height, 120 | graph_x_offset + day_width * index + day_offset, 121 | graph_y_offset + graph_height - day_stat_height, 122 | capstyle="round", fill=self.stat_color, width=self.stat_width) 123 | 124 | if self.stat_info_show[0]: 125 | self.main_canvas.create_text(graph_x_offset + day_width * index + day_offset, 126 | graph_y_offset + graph_height, 127 | text=value, fill=self.stat_text_color, 128 | font=ctk.CTkFont("Arial", 13, "bold")) 129 | 130 | if self.stat_info_show[1]: 131 | self.main_canvas.create_text(graph_x_offset + day_width * index + day_offset, 132 | graph_y_offset + graph_height + 40, 133 | text=key, fill=self.stat_title_color, 134 | font=ctk.CTkFont("Arial", 13, "bold")) 135 | 136 | def draw_stat_indicator(self, x2, y, title): 137 | self.main_canvas.create_line(10, y, x2, y, 138 | dash=[20], fill=self.indicator_line_color, capstyle="round", width=3) 139 | self.main_canvas.create_text(x2+5, y, anchor="w", text=title, fill=self.indicator_text_color, 140 | font=ctk.CTkFont("Arial", 15, "bold")) 141 | 142 | -------------------------------------------------------------------------------- /CTkDataVisualizingWidgets/ctk_calender.py: -------------------------------------------------------------------------------- 1 | import customtkinter as ctk 2 | import calendar 3 | from datetime import datetime 4 | import tkinter as tk 5 | 6 | class CTkCalendar(ctk.CTkFrame): 7 | """ 8 | Calendar widget to display certain month, each day is rendered as Label. 9 | 10 | If you do not define today_fg_color and today_text_color it will be rendered as other days 11 | """ 12 | def __init__(self, master, 13 | today_fg_color=None, 14 | today_text_color=None, 15 | width=250, 16 | height=250, 17 | fg_color=None, 18 | corner_radius=8, 19 | border_width=None, 20 | border_color=None, 21 | bg_color="transparent", 22 | background_corner_colors=None, 23 | title_bar_fg_color=None, 24 | title_bar_border_width=None, 25 | title_bar_border_color=None, 26 | title_bar_corner_radius=None, 27 | title_bar_text_color=None, 28 | title_bar_button_fg_color=None, 29 | title_bar_button_hover_color=None, 30 | title_bar_button_text_color=None, 31 | title_bar_button_border_width=None, 32 | title_bar_button_border_color=None, 33 | calendar_fg_color=None, 34 | calendar_border_width=None, 35 | calendar_border_color=None, 36 | calendar_corner_radius=None, 37 | calendar_text_color=None, 38 | calendar_text_fg_color=None, 39 | calendar_label_pad=1): 40 | 41 | super().__init__(master=master, 42 | width=width, 43 | height=height, 44 | fg_color=fg_color, 45 | corner_radius=corner_radius, 46 | border_width=border_width, 47 | border_color=border_color, 48 | bg_color=bg_color, 49 | background_corner_colors=background_corner_colors) 50 | 51 | # data 52 | self.today_text_color = today_text_color 53 | self.today_fg_color = today_fg_color 54 | self.today = self.current_date() 55 | self.day, self.month, self.year = self.today[:] 56 | self.labels_by_date = dict() 57 | self.month_label = ctk.StringVar(value=calendar.month_name[self.month]) 58 | self.year_label = ctk.IntVar(value=self.year) 59 | 60 | # data for title bar 61 | self.title_bar_fg_color = title_bar_fg_color 62 | self.title_bar_border_width = title_bar_border_width 63 | self.title_bar_border_color = title_bar_border_color 64 | self.title_bar_text_color = title_bar_text_color 65 | self.title_bar_button_fg_color = title_bar_button_fg_color 66 | self.title_bar_button_hover_color = title_bar_button_hover_color 67 | self.title_bar_button_text_color = title_bar_button_text_color 68 | self.title_bar_button_border_width = title_bar_button_border_width 69 | self.title_bar_button_border_color = title_bar_button_border_color 70 | self.title_bar_corner_radius = title_bar_corner_radius 71 | 72 | # data for calendar frame 73 | self.calendar_fg_color = calendar_fg_color 74 | self.calendar_border_width = calendar_border_width 75 | self.calendar_border_color = calendar_border_color 76 | self.calendar_corner_radius = calendar_corner_radius 77 | self.calendar_text_fg_color = calendar_text_fg_color 78 | self.calendar_text_color = calendar_text_color 79 | self.calendar_label_pad = calendar_label_pad 80 | 81 | # creating header and calendar frames 82 | self.content_frame = ctk.CTkFrame(self, fg_color="transparent", width=width, height=height) 83 | self.content_frame.pack(expand=True, fill="both", padx=corner_radius/3, pady=corner_radius/3) 84 | self.setup_header_frame() 85 | self.create_calendar_frame() 86 | 87 | # setting up the header frame 88 | def setup_header_frame(self): 89 | header_frame = ctk.CTkFrame(self.content_frame, fg_color=self.title_bar_fg_color, 90 | corner_radius=self.title_bar_corner_radius, 91 | border_color=self.title_bar_border_color, border_width=self.title_bar_border_width) 92 | 93 | ctk.CTkButton(header_frame, text="<", width=25, fg_color=self.title_bar_button_fg_color, 94 | hover_color=self.title_bar_button_hover_color, border_color=self.title_bar_button_border_color, 95 | border_width=self.title_bar_button_border_width, font=ctk.CTkFont("Arial", 11, "bold"), 96 | command=lambda: self.change_month(-1)).pack(side="left", padx=10) 97 | ctk.CTkLabel(header_frame, textvariable=self.month_label, font=ctk.CTkFont("Arial", 16, "bold"), 98 | fg_color="transparent").pack(side="left", fill="x", expand=True) 99 | ctk.CTkLabel(header_frame, textvariable=self.year_label, font=ctk.CTkFont("Arial", 16, "bold"), 100 | fg_color="transparent").pack(side="left", fill="x") 101 | ctk.CTkButton(header_frame, text=">", width=25, fg_color=self.title_bar_button_fg_color, 102 | hover_color=self.title_bar_button_hover_color, border_color=self.title_bar_button_border_color, 103 | border_width=self.title_bar_button_border_width, font=ctk.CTkFont("Arial", 11, "bold"), 104 | command=lambda: self.change_month(1)).pack(side="right", padx=10) 105 | 106 | header_frame.place(relx=0.5, rely=0.02, anchor="n", relheight=0.18, relwidth=0.95) 107 | 108 | def create_calendar_frame(self): 109 | # "updating" frames 110 | calendar_frame = ctk.CTkFrame(self.content_frame, fg_color=self.calendar_fg_color, 111 | corner_radius=self.calendar_corner_radius, 112 | border_width=self.calendar_border_width, border_color=self.calendar_border_color) 113 | current_month = calendar.monthcalendar(self.year, self.month) 114 | 115 | # grid 116 | calendar_frame.columnconfigure((0, 1, 2, 3, 4, 5, 6), weight=1, uniform="b") 117 | rows = tuple([i for i in range(len(current_month))]) 118 | calendar_frame.rowconfigure(rows, weight=1, uniform="b") 119 | 120 | # labels for days 121 | for row in range(len(current_month)): 122 | for column in range(7): 123 | if current_month[row][column] != 0: 124 | if self.today_fg_color is not None and self.year == self.today[2] and self.month == self.today[1] \ 125 | and current_month[row][column] == self.today[0]: 126 | label = ctk.CTkLabel(calendar_frame, text=str(current_month[row][column]), corner_radius=5, 127 | fg_color=self.today_fg_color, font=ctk.CTkFont("Arial", 11), 128 | text_color=self.today_text_color) 129 | else: 130 | label = ctk.CTkLabel(calendar_frame, text=str(current_month[row][column]), corner_radius=5, 131 | fg_color=self.calendar_text_fg_color, font=ctk.CTkFont("Arial", 11), 132 | text_color=self.calendar_text_color) 133 | 134 | self.labels_by_date[(current_month[row][column], self.month, self.year)] = label 135 | 136 | label.grid(row=row, column=column, sticky="nsew", padx=self.calendar_label_pad, 137 | pady=self.calendar_label_pad) 138 | 139 | calendar_frame.place(relx=0.5, rely=0.97, anchor="s", relheight=0.75, relwidth=0.95) 140 | 141 | def change_month(self, amount): 142 | self.month += amount 143 | if self.month < 1: 144 | self.year -= 1 145 | self.month = 12 146 | self.day = 1 147 | elif self.month > 12: 148 | self.year += 1 149 | self.month = 1 150 | self.day = 1 151 | 152 | self.month_label.set(calendar.month_name[self.month]) 153 | self.year_label.set(self.year) 154 | 155 | self.create_calendar_frame() 156 | 157 | def current_date(self) -> tuple[int, int, int]: 158 | date = str(datetime.now()).split() 159 | year, month, day = date[0].split("-") 160 | return int(day), int(month), int(year) 161 | --------------------------------------------------------------------------------