Skip to content

Commit

Permalink
Created a question data class to replace trie-like dictionary nesting…
Browse files Browse the repository at this point in the history
… while pickling
  • Loading branch information
Zanger67 committed Jul 20, 2024
1 parent 610b179 commit 7ccd03a
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 97 deletions.
4 changes: 2 additions & 2 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ QUESTIONS_PATH_FROM_README = my-submissions/
# want the README to appear?
README_PATH = ../
QUESTION_DATA_PATH = question_data/ # Official leetcode info on each question including
LEETCODE_QUESTION_DETAILS = leetcode_question_details.pkl # name, AC rate, difficulty, topics, etc.
LEETCODE_QUESTION_TOPICS = leetcode_question_topics.pkl
SUBMODULE_DATA_PATH = question_data/question_data/data/
LEETCODE_QUESTION_DETAILS = leetcode.pkl # name, AC rate, difficulty, topics, etc.

USER_DATA_PATH = user_data/ # Times of when code files were modified are stored
FILE_MODIFICATION_NAME = file_history.pkl # here so the program knows which question markdown
Expand Down
89 changes: 19 additions & 70 deletions main.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -475,73 +475,23 @@
" A dictionary containing the question details matched to the question's assigned number\n",
" '''\n",
" \n",
" question_data_folder = getenv('QUESTION_DATA_PATH')\n",
" question_details_file = getenv('LEETCODE_QUESTION_DETAILS')\n",
" question_data_folder = join(getenv('SUBMODULE_DATA_PATH'), getenv('LEETCODE_QUESTION_DETAILS'))\n",
"\n",
" if not isfile(join(question_data_folder, question_details_file)) :\n",
" print('Rerunning json-to-pkl parse and export due to the file(s) not being found.')\n",
" print()\n",
" import parse_official_question_data\n",
" \n",
" if not isfile(join(question_data_folder, question_details_file)) :\n",
" print('\\nError in parsing official question data. Exiting...')\n",
" if not isfile(question_data_folder) :\n",
" print('\\nError in parsing official question data. leetcode.pkl not found. Exiting...')\n",
" print()\n",
" exit()\n",
" else : \n",
" print('\\nFiles found. Importing now...\\n')\n",
"\n",
"\n",
" # schema: key=int(questionNumber) val=(title, titleSlug, paidOnly, difficulty, acRate)\n",
" with open(join(question_data_folder, question_details_file), 'rb') as fp:\n",
" with open(join(question_data_folder), 'rb') as fp:\n",
" questionDetailsDict = pickle.load(fp)\n",
" # print('Question Details dictionary')\n",
" # print(questionDetailsDict)\n",
"\n",
" return questionDetailsDict\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"@cache\n",
"def retrieveQuestionTopics() -> dict :\n",
" '''\n",
" Retrieves the topics associated with each question (e.g. Array, LinkedList, \n",
" BST, etc.) from the relevant `.pkl` file containing parsed official LeetCode json data.\n",
"\n",
" ### Returns :\n",
" questionDetailsDict : dict\n",
" A dictionary containing the question details matched to the question's assigned number\n",
" '''\n",
" \n",
" question_data_folder = getenv('QUESTION_DATA_PATH')\n",
" question_topics_file = getenv('LEETCODE_QUESTION_TOPICS')\n",
"\n",
" if not isfile(join(question_data_folder, question_topics_file)) :\n",
" print('Rerunning json-to-pkl parse and export due to the file(s) not being found.')\n",
" print()\n",
" import parse_official_question_data\n",
" \n",
" if not isfile(join(question_data_folder, question_topics_file)) :\n",
" print('\\nError in parsing official question data. Exiting...')\n",
" print()\n",
" exit()\n",
" else : \n",
" print('\\nFiles found. Importing now...\\n')\n",
"\n",
" # schema: key-int(questionNumber) val=List[str](topics)\n",
" questionTopicsDict = None\n",
" with open(join(question_data_folder, question_topics_file), 'rb') as fp:\n",
" questionTopicsDict = pickle.load(fp)\n",
" # print('Question Details dictionary')\n",
" # print(questionTopicsDict)\n",
"\n",
" return questionTopicsDict"
]
},
{
"cell_type": "code",
"execution_count": null,
Expand Down Expand Up @@ -607,7 +557,7 @@
"\n",
" try :\n",
" number = int(re.search(\"\\d{1,4}\", leetcodeFile).group()) # Takes the first full number as the question\n",
" level = questionDetailsDict[number][3][0].lower() # number and uses that as reference\n",
" level = questionDetailsDict[number].level # number and uses that as reference\n",
" # e.g. 'e123 v1.py' becomes 123\n",
" except AttributeError as ae :\n",
" print(f'Error in parsing {leetcodeFile}: Attribute Error encountered while trying to extract question number int(...).',\n",
Expand All @@ -623,7 +573,7 @@
" \n",
"\n",
" if number in questionDetailsDict :\n",
" title = f'[{questionDetailsDict[number][0]}](<https://leetcode.com/problems/{questionDetailsDict[number][1]}>)'\n",
" title = f'[{questionDetailsDict[number].title}](<https://leetcode.com/problems/{questionDetailsDict[number].slug}>)'\n",
" else :\n",
" title = f'Question {number}'\n",
" categories = set()\n",
Expand Down Expand Up @@ -863,14 +813,15 @@
"source": [
"def getCompletedQuestionsTopicLists(questionData: dict,\n",
" *,\n",
" questionTopicsDict: dict = retrieveQuestionTopics()) -> defaultdict :\n",
" questionTopicsDict: dict = retrieveQuestionDetails()) -> defaultdict :\n",
" \n",
" completedTopicLists = defaultdict(set)\n",
"\n",
" for question in questionData.keys() :\n",
" # Shouldn't occur but just in case\n",
" if question not in questionTopicsDict :\n",
" continue\n",
" for topic in questionTopicsDict[question] :\n",
" for topic in questionTopicsDict[question].topics :\n",
" completedTopicLists[topic].add(question)\n",
"\n",
" return completedTopicLists\n"
Expand Down Expand Up @@ -916,7 +867,6 @@
" questionData: dict,\n",
" *,\n",
" questionDetailsDict: dict = retrieveQuestionDetails(),\n",
" questionTopicsDict: dict = retrieveQuestionTopics(),\n",
" export: bool = False) -> str :\n",
" if questionNo in questionData :\n",
" questionData = questionData[questionNo]\n",
Expand Down Expand Up @@ -959,12 +909,12 @@
" f.write('\\n------\\n\\n')\n",
"\n",
" BY_TOPIC_FOLDER_PATH = getenv('TOPIC_MARKDOWN_PATH_IN_MARKDOWNS_FOLDER')\n",
" tpcs = 'N/A' if questionNo not in questionTopicsDict or len(questionTopicsDict[questionNo]) == 0 \\\n",
" else ', '.join([f'[{x}](<{join(BY_TOPIC_FOLDER_PATH, x)}.md>)' for x in questionTopicsDict[questionNo]])\n",
" tpcs = 'N/A' if questionNo not in questionDetailsDict or len(questionDetailsDict[questionNo].topics) == 0 \\\n",
" else ', '.join([f'[{x}](<{join(BY_TOPIC_FOLDER_PATH, x)}.md>)' for x in questionDetailsDict[questionNo].topics])\n",
" \n",
" f.write(f'> **Related Topics** : **{tpcs}**\\n>\\n')\n",
"\n",
" acrate = 'Unknown' if questionNo not in questionDetailsDict else f'{questionDetailsDict[questionNo][4]} %'\n",
" acrate = 'Unknown' if questionNo not in questionDetailsDict else f'{questionDetailsDict[questionNo].acRate} %'\n",
" f.write(f'> **Acceptance Rate** : **{acrate}**\\n\\n')\n",
" f.write('------\\n\\n')\n",
"\n",
Expand Down Expand Up @@ -1013,8 +963,7 @@
"def processMarkdownGeneration(questionData: dict,\n",
" reprocessMarkdown: Set[int],\n",
" *,\n",
" questionDetailsDict: dict = retrieveQuestionDetails(),\n",
" questionTopicsDict: dict = retrieveQuestionTopics()) -> None :\n",
" questionDetailsDict: dict = retrieveQuestionDetails()) -> None :\n",
" \n",
" # Create a folder to avoid errors if it doesn't already exist\n",
" markdownFolder = join(README_PATH, MARKDOWN_PATH)\n",
Expand All @@ -1026,13 +975,11 @@
" generate_markdown(questionNo, \n",
" questionData, \n",
" questionDetailsDict=questionDetailsDict, \n",
" questionTopicsDict=questionTopicsDict,\n",
" export=True)\n",
" else : # In order to assign the markdown paths\n",
" generate_markdown(questionNo, \n",
" questionData, \n",
" questionDetailsDict=questionDetailsDict, \n",
" questionTopicsDict=questionTopicsDict,\n",
" export=False)"
]
},
Expand Down Expand Up @@ -1514,7 +1461,11 @@
" file.write('\\n\\n')\n",
"\n",
" file.write('## Questions\\n')\n",
" file.write(dfQuestions.to_markdown(index=False))\n"
" file.write(dfQuestions.to_markdown(index=False))\n",
" \n",
" \n",
" file.write('\\n\\n')\n",
" file.write('<p align=\"right\">*This README was generated using [WikiLeet](<https://github.com/Zanger67/WikiLeet>)*</p>\\n')\n"
]
},
{
Expand All @@ -1539,7 +1490,6 @@
"\n",
"\n",
" questionDetailsDict = retrieveQuestionDetails()\n",
" questionTopicsDict = retrieveQuestionTopics()\n",
"\n",
" leetcodeFiles.sort()\n",
" contestLeetcodeFiles.sort()\n",
Expand Down Expand Up @@ -1595,8 +1545,7 @@
" print('Generating markdowns for each individual question...')\n",
" processMarkdownGeneration(questionData=questionData, \n",
" reprocessMarkdown=reprocessMarkdown, \n",
" questionDetailsDict=questionDetailsDict, \n",
" questionTopicsDict=questionTopicsDict)\n",
" questionDetailsDict=questionDetailsDict)\n",
" \n",
" # Produces a markdown where questions are sorted by the amount of code\n",
" # written for the question\n",
Expand Down
4 changes: 4 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -1329,6 +1329,10 @@ def exportPrimaryReadme(dfQuestions: DataFrame,

file.write('## Questions\n')
file.write(dfQuestions.to_markdown(index=False))


file.write('\n\n')
file.write('<p align="right">*This README was generated using [WikiLeet](<https://github.com/Zanger67/WikiLeet>)*</p>\n')


# In[ ]:
Expand Down
24 changes: 0 additions & 24 deletions questionData.py

This file was deleted.

34 changes: 34 additions & 0 deletions questionDataclass.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@


class questionDataclass:
def __init__(self,
*,
questionNo:int=-1,
acRate:float=None,
difficulty:str=None,
isFavor:bool=False,
paidOnly:bool=False,
title:str=None,
slug:str=None,
url:str=None,
topics:list=None,
hasSolution:bool=None,
hasVideoSolution:bool=None):
self.questionNo = questionNo
self.acRate = acRate
self.difficulty = difficulty
self.isFavor = isFavor
self.paidOnly = paidOnly
self.title = title
self.slug = slug
self.url = 'https://leetcode.com/problems/' + slug
self.topics = topics
self.hasSolution = hasSolution
self.hasVideoSolution = hasVideoSolution


def __str__(self):
return f"questionNo: {self.questionNo}, acRate: {self.acRate}, difficulty: {self.difficulty}, isFavor: {self.isFavor}, paidOnly: {self.paidOnly}, title: {self.title}, slug: {self.slug}, url: {self.url}, topics: {self.topics}, hasSolution: {self.hasSolution}, hasVideoSolution: {self.hasVideoSolution}"

def __repr__(self) -> str:
return f"questionNo: {self.questionNo}, acRate: {self.acRate}, difficulty: {self.difficulty}, isFavor: {self.isFavor}, paidOnly: {self.paidOnly}, title: {self.title}, slug: {self.slug}, url: {self.url}, topics: {self.topics}, hasSolution: {self.hasSolution}, hasVideoSolution: {self.hasVideoSolution}"

0 comments on commit 7ccd03a

Please sign in to comment.