Skip to content

Commit af2f6f6

Browse files
committed
submission command
1 parent 77e2d7b commit af2f6f6

File tree

5 files changed

+100
-33
lines changed

5 files changed

+100
-33
lines changed

leetcode/loader.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def _animate(self):
3131
for c in cycle(self.steps):
3232
if self.done:
3333
break
34-
print(f"\r{self.desc} {c}", flush=True, end="")
34+
print(f"\r{c} {self.desc}", flush=True, end="")
3535
sleep(self.timeout)
3636

3737
def __enter__(self):
@@ -41,7 +41,7 @@ def stop(self):
4141
self.done = True
4242
cols = get_terminal_size((80, 20)).columns
4343
print("\r" + " " * cols, end="", flush=True)
44-
print(f"\r{self.end}", flush=True)
44+
print(f"\r{self.end}", flush=True, end="")
4545

4646
def __exit__(self, exc_type, exc_value, tb):
4747
# handle exceptions with those variables ^

leetcode/main.py

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,12 @@
22
from leetcode.models import *
33
from leetcode.configuration import check_session_validity, UserConfig
44

5-
# IDEA: submit the code to the proper question
6-
# using the question slug and question ID that needs to be contained within the filename
7-
8-
# the file can be generated when the user displsays the question
9-
105
# TODO: pipes support
116
# TODO: add a command to open the question in editor
127
# TODO: add a command to show the solution in the terminal
138
# TODO: add a command to show the solution in the browser
9+
# TODO: problem with import in synced code or code to submit
10+
# TODO: random problem selector (from not accepted problems)
1411

1512
def positive_integer(value):
1613
try:
@@ -54,10 +51,11 @@ def main():
5451
today_problem_parser = subparsers.add_parser('today', help="Display today's problem.")
5552
today_problem_parser.set_defaults(func=QuestionOfToday)
5653

57-
# submission_parser = subparsers.add_parser('submission', help="Download submission code")
58-
# submission_parser.add_argument('question_slug', type=str, help='Title slug of the problem.')
59-
# submission_parser.add_argument('-l', '--list', action='store_true', help='List all submissions.')
60-
# submission_parser.set_defaults(func=submissionList)
54+
submission_parser = subparsers.add_parser('submission', help="Download submission code")
55+
submission_parser.add_argument('id', type=int, help='ID of the problem.')
56+
submission_parser.add_argument('-s', '--show', action='store_true', help='Show latest accepted code in the terminal.')
57+
submission_parser.add_argument('-d', '--download', action='store_true', help='Download the latest accepted code.')
58+
submission_parser.set_defaults(func=SubmissionList)
6159

6260
submission_parser = subparsers.add_parser('submit', help='Submit code answer')
6361
submission_parser.add_argument('question_slug', type=str, help="Title slug of the question")

leetcode/models/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
from leetcode.models.graphql_question_info_table import QuestionInfoTable
2525
from leetcode.models.graphql_question_of_today import QuestionOfToday
2626
from leetcode.models.graphql_submission_details import SubmissionDetails
27-
from leetcode.models.graphql_submission_list import SubmissionList
2827
from leetcode.models.graphql_user_problems_solved import UserProblemsSolved
2928
from leetcode.models.problem_by_id_slug import ProblemInfo
29+
from leetcode.models.graphql_submission_list import SubmissionList
3030
from leetcode.models.submit import SendSubmission

leetcode/models/graphql_submission_list.py

Lines changed: 80 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -28,36 +28,49 @@ def from_dict(cls, data):
2828
return cls(submissions=submissions)
2929

3030

31+
32+
# TODO: Emojis/colors for status display (Accepted, Wrong Answer, Runtime Error)
33+
# TODO: Handle empty submissions table
3134
class SubmissionList(QueryTemplate):
3235
def __init__(self):
3336
super().__init__()
3437
# Instance specific variables
35-
self.question_slug = ""
36-
self.list_view = False
38+
self.question_id: int = None
39+
self.show_terminal = False
3740
self.submission_download = False
3841

3942
self.graphql_query = None
4043
self.result = None
41-
self.params = {'offset': 0, 'limit': 20, 'lastKey': None, 'questionSlug': ""}
44+
self.params = {'offset': 0, 'limit': 20, 'lastKey': None, 'questionSlug': None}
4245

4346
def parse_args(self, args):
44-
self.params['questionSlug'] = args.question_slug
45-
if args.list:
46-
self.list_view = True
47-
else:
47+
self.question_id = args.id
48+
self.params['questionSlug'] = ProblemInfo.get_title_slug(self.question_id)
49+
50+
if getattr(args, 'show'):
51+
self.show_terminal = True
52+
53+
if getattr(args, 'download'):
4854
self.submission_download = True
4955

5056
def execute(self, args):
51-
self.parse_args(args)
52-
53-
self.graphql_query = GraphQLQuery(self.query, self.params)
54-
self.result = self.leet_API.post_query(self.graphql_query)
55-
self.result = QuestionSubmisstionList.from_dict(self.result['data'])
56-
if self.list_view:
57+
try:
58+
with Loader('Fetching submission list...', ''):
59+
self.parse_args(args)
60+
self.graphql_query = GraphQLQuery(self.query, self.params)
61+
self.result = self.leet_API.post_query(self.graphql_query)
62+
self.result = QuestionSubmisstionList.from_dict(self.result['data'])
63+
if not self.result.submissions:
64+
raise ValueError("Apparently you don't have any submissions for this problem.")
5765
self.show()
58-
if self.submission_download:
59-
print(self.get_code())
60-
66+
67+
if self.show_terminal:
68+
self.show_code()
69+
70+
if self.submission_download:
71+
self.download_submission()
72+
except Exception as e:
73+
console.print(f"{e.__class__.__name__}: {e}", style=ALERT)
6174

6275
def show(self):
6376
table = LeetTable()
@@ -72,9 +85,55 @@ def show(self):
7285
for x in submissions:
7386
table.add_row(x.id, x.title, x.statusDisplay, x.runtime, x.memory, x.langName)
7487
console.print(table)
88+
89+
90+
@staticmethod
91+
def fetch_accepted(submissions):
92+
return next((x for x in submissions if x.statusDisplay == 'Accepted'), None)
7593

76-
def get_code(self):
77-
# TODO: returning the code of the first submission for now
78-
submission_details = SubmissionDetails(self.result.submissions[0].id)
79-
submission_details.execute()
80-
return submission_details.result.code
94+
def show_code(self):
95+
try:
96+
with Loader('Fetching latest accepted code...', ''):
97+
acc_submission = self.fetch_accepted(self.result.submissions)
98+
99+
if not acc_submission:
100+
raise ValueError("No accepted submissions found.")
101+
102+
submission_id = acc_submission.id
103+
104+
query = self.parser.extract_query('SubmissionDetails')
105+
params = {'submissionId': submission_id}
106+
graphql_query = GraphQLQuery(query, params)
107+
result = self.leet_API.post_query(graphql_query)
108+
109+
code = result['data']['submissionDetails']['code']
110+
111+
console.print(rich.rule.Rule('Latest accepted code', style='bold blue'), width=100)
112+
console.print(rich.syntax.Syntax(code, 'python', theme='monokai', line_numbers=True), width=100)
113+
except Exception as e:
114+
console.print(f"{e.__class__.__name__}: {e}", style=ALERT)
115+
116+
def download_submission(self):
117+
try:
118+
with Loader('Downloading latest accepted code...', ''):
119+
acc_submission = self.fetch_accepted(self.result.submissions)
120+
121+
if not acc_submission:
122+
raise ValueError("No accepted submissions found.")
123+
124+
query = self.parser.extract_query('SubmissionDetails')
125+
params = {'submissionId': acc_submission.id}
126+
graphql_query = GraphQLQuery(query, params)
127+
result = self.leet_API.post_query(graphql_query)
128+
129+
code = result['data']['submissionDetails']['code']
130+
file_name = f"{acc_submission.titleSlug}.{acc_submission.id}.py"
131+
with open(file_name, 'w') as file:
132+
file.write(code)
133+
134+
console.print(f"File saved as {file_name}")
135+
except Exception as e:
136+
console.print(f"{e.__class__.__name__}: {e}", style=ALERT)
137+
138+
139+

two-sum.1008758093.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
class Solution:
2+
def twoSum(self, nums: List[int], target: int) -> List[int]:
3+
seen_numbers = {}
4+
for index, number in enumerate(nums):
5+
complement = target - number
6+
if complement in seen_numbers:
7+
return [index, seen_numbers[complement]]
8+
else:
9+
seen_numbers[number] = index
10+
return None

0 commit comments

Comments
 (0)