Skip to content

Commit 3d94468

Browse files
committed
class docstring and restructurization
1 parent abb9d57 commit 3d94468

File tree

1 file changed

+99
-58
lines changed

1 file changed

+99
-58
lines changed
Lines changed: 99 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
from leetcode.models import *
22

3-
@dataclass
4-
class Question():
5-
title: str
6-
status: str
7-
difficulty: str
8-
frontendQuestionId: int
9-
questionId: int
10-
113
@dataclass
124
class QueryResult(JSONWizard):
5+
@dataclass
6+
class Question():
7+
title: str
8+
status: str
9+
difficulty: str
10+
frontendQuestionId: int
11+
questionId: int
1312
total: int
1413
questions: List[Question]
1514

@@ -18,7 +17,7 @@ def from_dict(cls, data):
1817
total = data['problemsetQuestionList']['total']
1918
questions_data = data['problemsetQuestionList']['questions']
2019
questions = [
21-
Question(
20+
cls.Question(
2221
title=item.get('title'),
2322
status=item.get('status'),
2423
difficulty=item.get('difficulty'),
@@ -28,16 +27,13 @@ def from_dict(cls, data):
2827
for item in questions_data
2928
]
3029
return cls(total=total, questions=questions)
31-
32-
@dataclass
33-
class TotalCount(JSONWizard):
34-
total: int
30+
3531
class ProblemTotalCount(QueryTemplate):
3632
def __init__(self, filters={}):
3733
super().__init__()
3834
self.graphql_query = None
3935
self.result = None
40-
self.params = {'categorySlug': "", 'skip': 0, 'limit': 10, 'filters': filters}
36+
self.params = {'categorySlug': '', 'filters': filters}
4137

4238
self.execute()
4339

@@ -47,28 +43,110 @@ def execute(self):
4743

4844
def __call__(self, *args: Any, **kwds: Any) -> Any:
4945
return self.result['data']['problemsetQuestionList']['total']
50-
46+
5147

5248
class ProblemsetQuestionList(QueryTemplate):
49+
""" A class to represent a list of LeetCode problems.
50+
51+
Args:
52+
filters (dict, optional): Filters to apply to the query. Defaults to {}.
53+
- 'difficulty' (str, optional): Difficulty level. Valid values: 'EASY', 'MEDIUM', 'HARD'.
54+
- 'status' (str, optional): Status of the problem. Valid values: 'NOT_STARTED', 'TRIED', 'AC'.
55+
limit (int, optional): Maximum number of problems to retrieve. Defaults to None.
56+
skip (int, optional): Number of problems to skip. Defaults to 0.
57+
"""
58+
5359
def __init__(self, filters={}, limit=None, skip=0):
5460
super().__init__()
61+
5562
# Instance specific variables
5663
self.page : int = 1
5764
self.max_page : int = 0
5865
self.filters = filters
5966
self.limit = limit or self.config.user_config.get('question_list_limit')
6067
self.skip = skip
6168

62-
self.params = {'categorySlug': "", 'skip':self.skip, 'limit': self.limit, 'filters': self.filters}
69+
self.params = {'categorySlug': "",
70+
'skip':self.skip,
71+
'limit': self.limit,
72+
'filters': self.filters}
73+
6374
self.graphql_query = None
6475
self.result = None
6576

66-
67-
def parse_args(self, args):
77+
def fetch_data(self, parameters: Dict = None) -> QueryResult:
78+
""" Fetches the data from the LeetCode API.
79+
80+
Args:
81+
parameters (dict, optional): Parameters to pass to the query. Defaults to None.
82+
83+
Returns:
84+
QueryResult: The result of the query.
85+
"""
86+
87+
if parameters is None:
88+
parameters = self.params
89+
with Loader('Fetching problems...', ''):
90+
self.graphql_query = GraphQLQuery(self.query, parameters)
91+
self.result = self.leet_API.post_query(self.graphql_query) # Take the response from the API
92+
self.result = QueryResult.from_dict(self.result['data'])
93+
return self.result
94+
95+
def _execute(self, args):
96+
""" Executes the query with the given arguments and displays the result.
97+
98+
Args:
99+
args (argparse.Namespace): The arguments passed to the query.
100+
"""
101+
102+
self.__parse_args(args)
103+
self.result = self.fetch_data()
104+
self.show(self.result)
105+
106+
def show(self, query_result: Optional[QueryResult] = None) -> None:
107+
""" Displays the query result in a table.
108+
109+
Args:
110+
query_result (QueryResult, optional): The result of the query. Defaults to None.
111+
If the result is None, the method will try to fetch the data with defauly parameters and than display it.
112+
"""
113+
114+
if query_result is None:
115+
query_result = self.fetch_data()
116+
117+
displayed : int = self.limit * self.page if self.limit * self.page < query_result.total else self.result.total
118+
119+
table = LeetTable(title=f'Total number of problems retrieved: {query_result.total}\n',
120+
caption=f"Page #{self.page} / ({displayed}/{self.result.total})")
121+
122+
table.add_column('ID')
123+
table.add_column('Title')
124+
table.add_column('Status')
125+
table.add_column('Difficulty')
126+
for item in query_result.questions:
127+
table.add_row(item.questionId, item.title, item.status, item.difficulty)
128+
console.print(table)
129+
130+
def __validate_page(self):
131+
""" Validates the current page number.
132+
If the number is too large, sets the page number to the last page.
133+
"""
134+
135+
count = ProblemTotalCount().__call__()
136+
self.page = min(self.page, -(-count // self.limit))
137+
self.params['skip'] = self.limit * self.page - self.limit # update the skip value
138+
139+
def __parse_args(self, args):
140+
""" Parses the arguments passed to the query.
141+
142+
Args:
143+
args (argparse.Namespace): The arguments passed to the query.
144+
"""
145+
68146
# Parse status argument
69147
status_mapping = {"solved": "AC",
70-
"todo": "NOT_STARTED",
71-
"attempted": "TRIED"}
148+
"todo": "NOT_STARTED",
149+
"attempted": "TRIED"}
72150
status_argument = None
73151
for status_arg in status_mapping.keys():
74152
if getattr(args, status_arg):
@@ -81,42 +159,5 @@ def parse_args(self, args):
81159
# Parse the page argument
82160
self.page = getattr(args, 'page')
83161
self.params['skip'] = self.limit * self.page - self.limit
84-
85-
def execute(self, args):
86-
with Loader('Fetching problem list...', ''):
87-
self.parse_args(args)
88-
self.validate_page()
89-
90-
self.graphql_query = GraphQLQuery(self.query, self.params)
91-
self.result = self.leet_API.post_query(self.graphql_query) # Take the response from the API
92-
self.result = QueryResult.from_dict(self.result['data']) # Put the response into the dataclass
93-
94-
self.show()
95-
96-
def validate_page(self):
97-
""" Method to validate the page number. If number is too large,
98-
set the page number to the last page."""
99-
count = ProblemTotalCount().__call__()
100-
self.page = min(self.page, -(-count // self.limit))
101-
self.params['skip'] = self.limit * self.page - self.limit # update the skip value
102-
103-
def show(self):
104-
displayed : int = self.limit * self.page if self.limit * self.page < self.result.total else self.result.total
105-
106-
107-
table = LeetTable(title=f'Total number of problems retrieved: {self.result.total}\n',
108-
caption=f"Page #{self.page} / ({displayed}/{self.result.total})")
109-
110-
table.add_column('ID')
111-
table.add_column('Title')
112-
table.add_column('Status')
113-
table.add_column('Difficulty')
114-
for item in self.result.questions:
115-
table.add_row(item.questionId, item.title, item.status, item.difficulty)
116-
print(table)
117-
118-
def get_data(self):
119-
self.graphql_query = GraphQLQuery(self.query, self.params)
120-
self.result = self.leet_API.post_query(self.graphql_query)
121162

122-
return self.result['data']
163+
self.__validate_page()

0 commit comments

Comments
 (0)