uw-course 1.0.1__tar.gz → 2.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- uw_course-2.0.0/PKG-INFO +111 -0
- uw_course-2.0.0/README.md +80 -0
- uw_course-2.0.0/pyproject.toml +47 -0
- {uw_course-1.0.1 → uw_course-2.0.0}/uw_course/ClassSchedule/SearchInfo.py +2 -3
- {uw_course-1.0.1 → uw_course-2.0.0}/uw_course/ClassSchedule/__init__.py +0 -0
- {uw_course-1.0.1 → uw_course-2.0.0}/uw_course/ClassSchedule/runner.py +28 -17
- {uw_course-1.0.1 → uw_course-2.0.0}/uw_course/DB/__init__.py +0 -0
- {uw_course-1.0.1 → uw_course-2.0.0}/uw_course/DB/dbClass.py +20 -0
- {uw_course-1.0.1 → uw_course-2.0.0}/uw_course/Utiles/__init__.py +0 -0
- {uw_course-1.0.1 → uw_course-2.0.0}/uw_course/Utiles/manageDBClass.py +5 -0
- uw_course-2.0.0/uw_course/Utiles/randomColor.py +28 -0
- {uw_course-1.0.1 → uw_course-2.0.0}/uw_course/__init__.py +0 -0
- uw_course-2.0.0/uw_course/main.py +16 -0
- uw_course-2.0.0/uw_course/pdfschedule.py +385 -0
- uw_course-2.0.0/uw_course/setting.py +10 -0
- uw_course-2.0.0/uw_course/ui/__init__.py +1 -0
- uw_course-2.0.0/uw_course/ui/app.py +730 -0
- uw_course-2.0.0/uw_course/ui/components.py +99 -0
- uw_course-2.0.0/uw_course/ui/constants.py +9 -0
- uw_course-2.0.0/uw_course/ui/schedule_view.py +87 -0
- uw_course-2.0.0/uw_course.egg-info/PKG-INFO +111 -0
- {uw_course-1.0.1 → uw_course-2.0.0}/uw_course.egg-info/SOURCES.txt +7 -2
- {uw_course-1.0.1 → uw_course-2.0.0}/uw_course.egg-info/requires.txt +4 -4
- uw_course-1.0.1/PKG-INFO +0 -95
- uw_course-1.0.1/README.md +0 -74
- uw_course-1.0.1/pyproject.toml +0 -36
- uw_course-1.0.1/uw_course/Utiles/colorMessage.py +0 -9
- uw_course-1.0.1/uw_course/Utiles/randomColor.py +0 -16
- uw_course-1.0.1/uw_course/main.py +0 -85
- uw_course-1.0.1/uw_course/setting.py +0 -5
- uw_course-1.0.1/uw_course.egg-info/PKG-INFO +0 -95
- {uw_course-1.0.1 → uw_course-2.0.0}/LICENSE +0 -0
- {uw_course-1.0.1 → uw_course-2.0.0}/setup.cfg +0 -0
- {uw_course-1.0.1 → uw_course-2.0.0}/uw_course.egg-info/dependency_links.txt +0 -0
- {uw_course-1.0.1 → uw_course-2.0.0}/uw_course.egg-info/entry_points.txt +0 -0
- {uw_course-1.0.1 → uw_course-2.0.0}/uw_course.egg-info/top_level.txt +0 -0
uw_course-2.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: uw-course
|
|
3
|
+
Version: 2.0.0
|
|
4
|
+
Summary: A course helper tool for managing UW courses schedule
|
|
5
|
+
Author-email: Jiucheng Zang <git.jiucheng@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/zangjiucheng/uw-course
|
|
8
|
+
Project-URL: Repository, https://github.com/zangjiucheng/uw-course
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
13
|
+
Classifier: Operating System :: MacOS
|
|
14
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
15
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
16
|
+
Classifier: Topic :: Education
|
|
17
|
+
Classifier: Topic :: Office/Business :: Scheduling
|
|
18
|
+
Requires-Python: >=3.10
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Requires-Dist: attrs
|
|
22
|
+
Requires-Dist: click
|
|
23
|
+
Requires-Dist: PyYAML
|
|
24
|
+
Requires-Dist: reportlab
|
|
25
|
+
Requires-Dist: certifi
|
|
26
|
+
Requires-Dist: dnspython
|
|
27
|
+
Requires-Dist: Pillow
|
|
28
|
+
Requires-Dist: pymongo
|
|
29
|
+
Requires-Dist: textual
|
|
30
|
+
Dynamic: license-file
|
|
31
|
+
|
|
32
|
+
# uw-course
|
|
33
|
+
|
|
34
|
+
[](https://badge.fury.io/py/uw-course)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
This is a project for UWaterloo students to help them get course information and generate a schedule for the next term.
|
|
38
|
+
|
|
39
|
+
MongoDB DashBoard: [LINK](https://charts.mongodb.com/charts-project-0-cbzai/public/dashboards/091bc68f-76df-48c0-aa69-b21af14c0a8a)
|
|
40
|
+
|
|
41
|
+
### Example Schedule:
|
|
42
|
+
|
|
43
|
+

|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
### Install Steps:
|
|
48
|
+
1. Install Python3 (>= 3.10) [Python Website](https://www.python.org/downloads/)
|
|
49
|
+
2. ```bash
|
|
50
|
+
pip install uw-course
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
### Usage (TUI)
|
|
56
|
+
|
|
57
|
+
Run the terminal UI:
|
|
58
|
+
```bash
|
|
59
|
+
uw-course
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
You can:
|
|
63
|
+
- Check course details
|
|
64
|
+
- Build a schedule manually or load a plan file
|
|
65
|
+
- View the weekly schedule in the TUI
|
|
66
|
+
- Export the `.out` schedule to PDF
|
|
67
|
+
|
|
68
|
+
#### Schedule Plan File Format
|
|
69
|
+
1. Create a new file named `schema.txt`
|
|
70
|
+
2. Edit `schema.txt` with the following format:
|
|
71
|
+
```txt
|
|
72
|
+
Class{year}{Winter/Spring/Fall}
|
|
73
|
+
|
|
74
|
+
{Course}{CourseName}, {ClassID}
|
|
75
|
+
{Course}{CourseName}, {ClassID}
|
|
76
|
+
...
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Example:
|
|
80
|
+
```txt
|
|
81
|
+
Class2025Winter
|
|
82
|
+
|
|
83
|
+
PHYS 234, 7166
|
|
84
|
+
CS 431, 8788
|
|
85
|
+
PMATH 351, 6382
|
|
86
|
+
CO 353, 6157
|
|
87
|
+
STAT 231, 6097
|
|
88
|
+
AMATH 250, 5967
|
|
89
|
+
```
|
|
90
|
+
3. Use the TUI to select “Load Plan” and provide the file path (default: `uw-course-files/schema.txt`).
|
|
91
|
+
4. The program will generate `uw-course-files/schedule.out`, and you can export it to PDF from the TUI.
|
|
92
|
+
|
|
93
|
+
#### Output Location
|
|
94
|
+
All generated files are stored in `uw-course-files/`:
|
|
95
|
+
- `uw-course-files/schedule.out`
|
|
96
|
+
- `uw-course-files/schedule.pdf`
|
|
97
|
+
- `uw-course-files/schema.txt` (if saved from the TUI)
|
|
98
|
+
|
|
99
|
+
#### Any Idea or Question, welcome send me an email via: j7zang@uwaterloo.ca
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Credits
|
|
104
|
+
|
|
105
|
+
PDF export uses a modified version of `pdfschedule` by John Thorvald Wodder II. Thanks for the original project.
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## License
|
|
110
|
+
|
|
111
|
+
This project is open-source and can be modified and used for personal or educational purposes. Attribution to the original creator is appreciated. (MIT License)
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# uw-course
|
|
2
|
+
|
|
3
|
+
[](https://badge.fury.io/py/uw-course)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
This is a project for UWaterloo students to help them get course information and generate a schedule for the next term.
|
|
7
|
+
|
|
8
|
+
MongoDB DashBoard: [LINK](https://charts.mongodb.com/charts-project-0-cbzai/public/dashboards/091bc68f-76df-48c0-aa69-b21af14c0a8a)
|
|
9
|
+
|
|
10
|
+
### Example Schedule:
|
|
11
|
+
|
|
12
|
+

|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
### Install Steps:
|
|
17
|
+
1. Install Python3 (>= 3.10) [Python Website](https://www.python.org/downloads/)
|
|
18
|
+
2. ```bash
|
|
19
|
+
pip install uw-course
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
### Usage (TUI)
|
|
25
|
+
|
|
26
|
+
Run the terminal UI:
|
|
27
|
+
```bash
|
|
28
|
+
uw-course
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
You can:
|
|
32
|
+
- Check course details
|
|
33
|
+
- Build a schedule manually or load a plan file
|
|
34
|
+
- View the weekly schedule in the TUI
|
|
35
|
+
- Export the `.out` schedule to PDF
|
|
36
|
+
|
|
37
|
+
#### Schedule Plan File Format
|
|
38
|
+
1. Create a new file named `schema.txt`
|
|
39
|
+
2. Edit `schema.txt` with the following format:
|
|
40
|
+
```txt
|
|
41
|
+
Class{year}{Winter/Spring/Fall}
|
|
42
|
+
|
|
43
|
+
{Course}{CourseName}, {ClassID}
|
|
44
|
+
{Course}{CourseName}, {ClassID}
|
|
45
|
+
...
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Example:
|
|
49
|
+
```txt
|
|
50
|
+
Class2025Winter
|
|
51
|
+
|
|
52
|
+
PHYS 234, 7166
|
|
53
|
+
CS 431, 8788
|
|
54
|
+
PMATH 351, 6382
|
|
55
|
+
CO 353, 6157
|
|
56
|
+
STAT 231, 6097
|
|
57
|
+
AMATH 250, 5967
|
|
58
|
+
```
|
|
59
|
+
3. Use the TUI to select “Load Plan” and provide the file path (default: `uw-course-files/schema.txt`).
|
|
60
|
+
4. The program will generate `uw-course-files/schedule.out`, and you can export it to PDF from the TUI.
|
|
61
|
+
|
|
62
|
+
#### Output Location
|
|
63
|
+
All generated files are stored in `uw-course-files/`:
|
|
64
|
+
- `uw-course-files/schedule.out`
|
|
65
|
+
- `uw-course-files/schedule.pdf`
|
|
66
|
+
- `uw-course-files/schema.txt` (if saved from the TUI)
|
|
67
|
+
|
|
68
|
+
#### Any Idea or Question, welcome send me an email via: j7zang@uwaterloo.ca
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Credits
|
|
73
|
+
|
|
74
|
+
PDF export uses a modified version of `pdfschedule` by John Thorvald Wodder II. Thanks for the original project.
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## License
|
|
79
|
+
|
|
80
|
+
This project is open-source and can be modified and used for personal or educational purposes. Attribution to the original creator is appreciated. (MIT License)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "uw-course"
|
|
7
|
+
version = "2.0.0"
|
|
8
|
+
description = "A course helper tool for managing UW courses schedule"
|
|
9
|
+
authors = [
|
|
10
|
+
{ name = "Jiucheng Zang", email = "git.jiucheng@gmail.com" }
|
|
11
|
+
]
|
|
12
|
+
license = "MIT"
|
|
13
|
+
readme = "README.md"
|
|
14
|
+
requires-python = ">=3.10"
|
|
15
|
+
dependencies = [
|
|
16
|
+
"attrs",
|
|
17
|
+
"click",
|
|
18
|
+
"PyYAML",
|
|
19
|
+
"reportlab",
|
|
20
|
+
"certifi",
|
|
21
|
+
"dnspython",
|
|
22
|
+
"Pillow",
|
|
23
|
+
"pymongo",
|
|
24
|
+
"textual"
|
|
25
|
+
]
|
|
26
|
+
classifiers = [
|
|
27
|
+
"Programming Language :: Python :: 3.10",
|
|
28
|
+
"Programming Language :: Python :: 3.11",
|
|
29
|
+
"Programming Language :: Python :: 3.12",
|
|
30
|
+
"Programming Language :: Python :: 3.13",
|
|
31
|
+
"Operating System :: MacOS",
|
|
32
|
+
"Operating System :: POSIX :: Linux",
|
|
33
|
+
"Operating System :: Microsoft :: Windows",
|
|
34
|
+
"Topic :: Education",
|
|
35
|
+
"Topic :: Office/Business :: Scheduling",
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
[project.urls]
|
|
39
|
+
Homepage = "https://github.com/zangjiucheng/uw-course"
|
|
40
|
+
Repository = "https://github.com/zangjiucheng/uw-course"
|
|
41
|
+
|
|
42
|
+
[project.scripts]
|
|
43
|
+
uw-course = "uw_course.main:main"
|
|
44
|
+
|
|
45
|
+
[tool.pypi]
|
|
46
|
+
repository = "https://pypi.org/project/uw-course"
|
|
47
|
+
github = "zangjiucheng/uw-course"
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import re
|
|
2
|
-
from ..Utiles.colorMessage import *
|
|
3
2
|
|
|
4
3
|
|
|
5
4
|
class Course():
|
|
@@ -20,7 +19,7 @@ class Course():
|
|
|
20
19
|
self.courseIndex = course['ClassIndex']
|
|
21
20
|
self.courseTitle = course['classTitle']
|
|
22
21
|
self.courseSeat = course['availableSeat']
|
|
23
|
-
if re.search("\d:\d*", self.time):
|
|
22
|
+
if re.search(r"\d:\d*", self.time):
|
|
24
23
|
self.startTime = self.time[0:5]
|
|
25
24
|
self.endTime = self.time[6:11]
|
|
26
25
|
StartTimeFlag = False
|
|
@@ -37,7 +36,7 @@ class Course():
|
|
|
37
36
|
self.weekDay = "H" if self.time[11:15] == "Th" else self.time[11:15]
|
|
38
37
|
self.writeSchedule()
|
|
39
38
|
else:
|
|
40
|
-
print(
|
|
39
|
+
print("Z_Z For course %s in class %s, Time Data Error Z_Z" % (self.courseIndex, self.classNum))
|
|
41
40
|
|
|
42
41
|
def writeSchedule(self):
|
|
43
42
|
self.fileOut.write(
|
|
File without changes
|
|
@@ -1,38 +1,49 @@
|
|
|
1
|
-
from .SearchInfo import Course
|
|
2
|
-
from
|
|
3
|
-
from
|
|
4
|
-
from ..Utiles.colorMessage import *
|
|
1
|
+
from uw_course.ClassSchedule.SearchInfo import Course
|
|
2
|
+
from uw_course.Utiles.randomColor import randomColor, randomGray
|
|
3
|
+
from uw_course.setting import Setting
|
|
5
4
|
|
|
6
5
|
from os import remove
|
|
7
6
|
|
|
8
7
|
setting = Setting()
|
|
9
8
|
|
|
10
9
|
|
|
11
|
-
def
|
|
10
|
+
def get_course_detail(dbClassUW, courseIndex):
|
|
12
11
|
CourseDescribe = dbClassUW.CourseDescribe
|
|
12
|
+
if not courseIndex or " " not in courseIndex:
|
|
13
|
+
return None
|
|
13
14
|
faculty = courseIndex.split(" ")[0]
|
|
14
15
|
courseNum = courseIndex.split(" ")[1]
|
|
15
16
|
FacultyList = CourseDescribe.find({"faculty": faculty})
|
|
16
17
|
for course in FacultyList:
|
|
17
|
-
if course
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
18
|
+
if course.get("courseIndex") == courseNum:
|
|
19
|
+
return course
|
|
20
|
+
return None
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def SearchCourse(dbClassUW, courseIndex):
|
|
24
|
+
course = get_course_detail(dbClassUW, courseIndex)
|
|
25
|
+
if not course:
|
|
26
|
+
print("@_@ Course %s Not Found @_@" % (courseIndex))
|
|
27
|
+
return
|
|
28
|
+
print("\n" + "$" * 50 + "\n\n")
|
|
29
|
+
print("Description: ", end="")
|
|
30
|
+
print(course.get("courseDescription"))
|
|
31
|
+
print("\ncourseCredit: ", end="")
|
|
32
|
+
print(course.get("courseCredit"))
|
|
33
|
+
print("\n\n" + "$" * 50)
|
|
25
34
|
print("\n\n")
|
|
26
35
|
|
|
27
36
|
|
|
28
|
-
def SearchAvalibleInTerm(dbClassUW, courseIndex, classNum=None):
|
|
37
|
+
def SearchAvalibleInTerm(dbClassUW, courseIndex, classNum=None, quiet=False):
|
|
29
38
|
ClassSchedule = dbClassUW.ClassSchedule
|
|
30
39
|
courseSelect = ClassSchedule.find({"ClassIndex": courseIndex})
|
|
31
40
|
if courseSelect == None:
|
|
32
|
-
|
|
41
|
+
if not quiet:
|
|
42
|
+
print("@_@ Course %s Not Found in %s @_@" % (courseIndex, dbClassUW.ClassCollectionName))
|
|
33
43
|
return None
|
|
34
44
|
else:
|
|
35
|
-
|
|
45
|
+
if not quiet:
|
|
46
|
+
print("!! Found Course %s in %s !!" % (courseIndex, dbClassUW.ClassCollectionName))
|
|
36
47
|
if classNum != None:
|
|
37
48
|
return [courseIndex, classNum]
|
|
38
49
|
return [courseIndex]
|
|
@@ -41,7 +52,7 @@ def SearchAvalibleInTerm(dbClassUW, courseIndex, classNum=None):
|
|
|
41
52
|
def makeSchedule(dbClassUW, courseWishList: list, gray: bool=False):
|
|
42
53
|
classSchedule = dbClassUW.ClassSchedule
|
|
43
54
|
if gray:
|
|
44
|
-
print(
|
|
55
|
+
print("!! Make Schedule with Gray Color !!")
|
|
45
56
|
try:
|
|
46
57
|
remove(setting.outDir)
|
|
47
58
|
except:
|
|
File without changes
|
|
@@ -23,3 +23,23 @@ class dbClass:
|
|
|
23
23
|
self.ClassCollectionName = collectionName
|
|
24
24
|
self.ClassDATABASE.selectCollection(self.ClassCollectionName)
|
|
25
25
|
self.ClassSchedule = self.ClassDATABASE.mongo_collection
|
|
26
|
+
|
|
27
|
+
def listClassCollections(self):
|
|
28
|
+
collections = self.ClassDATABASE.listCollections()
|
|
29
|
+
term_order = {"Winter": 0, "Spring": 1, "Fall": 2}
|
|
30
|
+
|
|
31
|
+
def sort_key(name):
|
|
32
|
+
if not name.startswith("Class"):
|
|
33
|
+
return (9999, 99, name)
|
|
34
|
+
tail = name[len("Class") :]
|
|
35
|
+
year = tail[:4]
|
|
36
|
+
term = tail[4:]
|
|
37
|
+
try:
|
|
38
|
+
year_value = int(year)
|
|
39
|
+
except ValueError:
|
|
40
|
+
year_value = 9999
|
|
41
|
+
term_value = term_order.get(term, 99)
|
|
42
|
+
return (year_value, term_value, name)
|
|
43
|
+
|
|
44
|
+
class_names = [name for name in collections if name.startswith("Class")]
|
|
45
|
+
return sorted(class_names, key=sort_key, reverse=True)
|
|
File without changes
|
|
@@ -16,5 +16,10 @@ class connectDB:
|
|
|
16
16
|
def selectCollection(self, collection_name):
|
|
17
17
|
self.mongo_collection = self.mongo_db[collection_name]
|
|
18
18
|
|
|
19
|
+
def listCollections(self):
|
|
20
|
+
if self.mongo_db is None:
|
|
21
|
+
return []
|
|
22
|
+
return self.mongo_db.list_collection_names()
|
|
23
|
+
|
|
19
24
|
def closeDB(self):
|
|
20
25
|
self.client.close()
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from random import choice
|
|
2
|
+
|
|
3
|
+
_PALETTE = [
|
|
4
|
+
"#1F77B4", # blue
|
|
5
|
+
"#FF7F0E", # orange
|
|
6
|
+
"#2CA02C", # green
|
|
7
|
+
"#D62728", # red
|
|
8
|
+
"#9467BD", # purple
|
|
9
|
+
"#8C564B", # brown
|
|
10
|
+
"#E377C2", # pink
|
|
11
|
+
"#7F7F7F", # gray
|
|
12
|
+
"#BCBD22", # olive
|
|
13
|
+
"#17BECF", # cyan
|
|
14
|
+
"#4E79A7", # blue
|
|
15
|
+
"#F28E2B", # orange
|
|
16
|
+
"#59A14F", # green
|
|
17
|
+
"#E15759", # red
|
|
18
|
+
"#76B7B2", # teal
|
|
19
|
+
"#EDC948", # yellow
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def randomColor():
|
|
24
|
+
return choice(_PALETTE)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def randomGray():
|
|
28
|
+
return "#9E9E9E"
|
|
File without changes
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
if __package__ in (None, ""):
|
|
5
|
+
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
|
|
6
|
+
__package__ = "uw_course"
|
|
7
|
+
|
|
8
|
+
from uw_course.ui.app import run_app
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def main():
|
|
12
|
+
run_app()
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
if __name__ == "__main__":
|
|
16
|
+
main()
|