LeetCode is now the “newbie village” that almost everyone must brush before applying for a job. Every job seeker must brush it before an interview. Without further ado, let’s see what LeetCode is all about

The interviewer won’t look at your Leetcode’s RepO on Github either, but it’s great if you have one, and a lot of gurus will swipe it and put it on Github, as well as newbies. We’ll find that the masters’ README is super good-looking and easy to find later, but the novice’s naming is messy and not standardized at all, making it very difficult to find. This happened to me, so I decided to refactor the directory structure to produce a better looking one.

Let’s take a look at the generated effect first. For more details, see here

Go straight to the operation section!

preparation

Create a repository on Github called Leetcode or algorithms_and_oj like mine. Then clone git from Github.

Then, install the libraries required for the project ahead:

pip install requests
Copy the code

To analyze

First, we need to configure our paths (the following paths are configured according to our project and need to be modified according to our own requirements).

class Config:
    "" some config, such as your github page here need to configure your own project address 1.   Path 2 to the local repository.   Github repository leetcode solution path ""
    local_path = '/home/yuan/PycharmProjects/algorithms_and_oj'
    # solution of leetcode
    github_leetcode_url = 'https://github.com/hey-bruce/algorithms_and_oj/blob/master/leetcode-algorithms/'
    # solution of pat,  I haven't used it yet
    github_pat_url = 'https://github.com/hey-bruce/algorithms_and_oj/blob/master/pat-algorithms/'
    leetcode_url = 'https://leetcode.com/problems/'
Copy the code

What information do we need, the ID, title, URL, difficulty of each Question, what language has been used to solve it, etc., so we naturally construct a Question class

class Question:
    """ this class used to store the inform of every question """

    def __init__(self, id_, name, url, lock, difficulty):
        self.id_ = id_
        self.title = name
        # the problem description url  Problem description page
        self.url = url
        self.lock = lock  # Boolean, locked means need to buy
        self.difficulty = difficulty
        # the solution url
        self.python = ' '
        self.java = ' '
        self.javascript = ' '
        self.c_plus_plus = ' '

    def __repr__(self):
        Return: """ """ "
        return str(self.id_) + ' ' + str(self.title) + ' ' + str(self.url)
Copy the code

Next, we’re going to get from the LeetCode problem, in the Google check, just found https://leetcode.com/api/problems/algorithms/ returns json data. With a little analysis (which you can easily spot by looking at the data yourself, although Leetcode doesn’t have an API description page), you can see that frontend_question_id in stat is the address of the URL corresponding to id, question__title_slug, Question__title corresponds to the name of the question, and PAId_only indicates whether a purchase is required. Difficulty D. Then we can write the code that gets the LeetCode information.

def get_leetcode_problems(self):
    """ used to get leetcode inform :return: """
    # we should look the response data carefully to find law
    # return byte. content type is byte
    content = requests.get('https://leetcode.com/api/problems/algorithms/').content
    # get all problems
    self.questions = json.loads(content)['stat_status_pairs']
    # print(self.questions)
    difficultys = ['Easy'.'Medium'.'Hard']
    for i in range(len(self.questions) - 1.- 1.- 1):
        question = self.questions[i]
        name = question['stat'] ['question__title']
        url = question['stat'] ['question__title_slug']
        id_ = str(question['stat'] ['frontend_question_id'])
        if int(id_) < 10:
            id_ = '00' + id_
        elif int(id_) < 100:
            id_ = '0' + id_
        lock = question['paid_only']
        if lock:
            self.locked += 1
        difficulty = difficultys[question['difficulty'] ['level'] - 1]
        url = Config.leetcode_url + url + '/description/'
        q = Question(id_, name, url, lock, difficulty)
        # we'll put it in the class after this, so don't worry
        The reason why we use a table and table_item is because, what language are we going to use when we solve the problem later
        self.table.append(q.id_)
        self.table_item[q.id_] = q
    return self.table, self.table_item
Copy the code

We need something to keep track of our CompleteInform class:

class CompleteInform:
    "" this is statistic inform, how many questions have been completed in each language ""

    def __init__(self):
        self.solved = {
            'python': 0.'c++': 0.'java': 0.'javascript': 0
        }
        self.total = 0

    def __repr__(self):
        return str(self.solved)
Copy the code

And then we create a folder for the title based on the title information,

def __create_folder(self, oj_name):
    "" oj_name will be followed by 'leetcode', this is done late, I want to extend to generate other Oj table ""
    oj_algorithms = Config.local_path + '/' + oj_name + '-algorithms'
    if os.path.exists(oj_algorithms):
        print(oj_name, ' algorithms is already exits')
    else:
        print('creating {} algorithms.... '.format(oj_name))
        os.mkdir(oj_algorithms)
    for item in self.table_item.values():
        question_folder_name = oj_algorithms + '/' + item.id_ + '. ' + item.title
        if not os.path.exists(question_folder_name):
            print(question_folder_name + 'is not exits, create it now.... ')
            os.mkdir(question_folder_name)

# here will be passed a 'leetcode', set the oJ name for easy extension
def update_table(self, oj):
    # the complete inform should be update
    complete_info = CompleteInform()
    self.get_leetcode_problems()
    # the total problem nums
    complete_info.total = len(self.table)
    self.__create_folder(oj)
    oj_algorithms = Config.local_path + '/' + oj + '-algorithms'
    # Check os.walk to see what exactly is returned
    for _, folders, _ in os.walk(oj_algorithms):
        for folder in folders:
            for _, _, files in os.walk(os.path.join(oj_algorithms, folder)):
                iflen(files) ! =0:
                    complete_info.complete_num += 1
                for item in files:
                    if item.endswith('.py') :# This section can be written as a function, but I seem to have some design problems, not easy to refactor, please think for yourself
                        complete_info.solved['python'] + =1
                        folder_url = folder.replace(' '."% 20")
                        folder_url = os.path.join(folder_url, item)
                        folder_url = os.path.join(Config.github_leetcode_url, folder_url)
                        self.table_item[folder[:3]].python = '[python]({})'.format(folder_url)
                    elif item.endswith('.java'):
                        complete_info.solved['java'] + =1
                        folder_url = folder.replace(' '."% 20")
                        folder_url = os.path.join(folder_url, item)
                        folder_url = os.path.join(Config.github_leetcode_url, folder_url)
                        self.table_item[folder[:3]].java = '[Java]({})'.format(folder_url)
                    elif item.endswith('.cpp'):
                        complete_info.solved['c++'] + =1
                        folder_url = folder.replace(' '."% 20")
                        folder_url = os.path.join(folder_url, item)
                        folder_url = os.path.join(Config.github_leetcode_url, folder_url)
                        self.table_item[folder[:3]].c_plus_plus = '[C++]({})'.format(folder_url)
                    elif item.endswith('.js'):
                        complete_info.solved['javascript'] + =1
                        folder_url = folder.replace(' '."% 20")
                        folder_url = os.path.join(folder_url, item)
                        folder_url = os.path.join(Config.github_leetcode_url, folder_url)
                        self.table_item[folder[:3]].javascript = '[JavaScript]({})'.format(folder_url)
    The Readme class used here is to write files. It is not particularly important
    readme = Readme(complete_info.total, complete_info.complete_num, complete_info.solved)
    readme.create_leetcode_readme([self.table, self.table_item])
    print('-------the complete inform-------')
    print(complete_info.solved)
Copy the code

The Readme class is used to generate the readme.md file, which is relatively simple to read and write. You’re smart enough to know when you see it. (Just a little bit about the table generation rules in Markdown)

class Readme:
    """ generate folder and markdown file update README.md when you finish one problem by some language """

    def __init__(self, total, solved, others):
        """ :param total: Total Problems nums :param solved: Solved Problem nums :param Others: Not yet
        self.total = total
        self.solved = solved
        self.others = others
        self.time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
        self.msg = '# Keep thinking, keep alive\n' \
                   'Until {}, I have solved **{}** / **{}** problems. ' \
                   '\n\nCompletion statistic: ' \
                   '\n1. JavaScript: {javascript} ' \
                   '\n2. Python: {python}' \
                   '\n3. C++: {c++}' \
                   '\n4. Java: {java}' \
                   '\n\nNote: :lock: means you need to buy a book from LeetCode\n'.format(
                    self.time, self.solved, self.total, **self.others)

    def create_leetcode_readme(self, table_instance):
        """ create REAdME.md :return: """
        file_path = Config.local_path + '/README.md'
        # write some basic inform about leetcode
        with open(file_path, 'w') as f:
            f.write(self.msg)
            f.write('\n----------------\n')

        with open(file_path, 'a') as f:
            f.write('## LeetCode Solution Table\n')
            f.write('| ID | Title | Difficulty | JavaScript | Python | C++ | Java |\n')
            f.write('| : - : * 7 + '|\n')
            table, table_item = table_instance
            for index in table:
                item = table_item[index]
                if item.lock:
                    _lock = ':lock:'
                else:
                    _lock = ' '
                data = {
                    'id': item.id_,
                    'title': '[] {}, {} {}'.format(item.title, item.url, _lock),
                    'difficulty': item.difficulty,
                    'js': item.javascript if item.javascript else 'To Do'.'python': item.python if item.python else 'To Do'.'c++': item.c_plus_plus if item.c_plus_plus else 'To Do'.'java': item.java if item.java else 'To Do'
                }
                line = '|{id}|{title}|{difficulty}|{js}|{python}|{c++}|{java}|\n'.format(**data)
                f.write(line)
            print('README.md was created..... ')
Copy the code

(This can run, welcome to use)

——- source code for a better reading experience, see here, code usage

#! /usr/bin/env python
# Created by Bruce yuan on 18-1-22.
import requests
import os
import json
import time

class Config:
    "" some config, such as your github page here need to configure your own project address 1.   Path 2 to the local repository.   Github repository leetcode solution path ""
    local_path = '/home/yuan/PycharmProjects/algorithms_and_oj'
    # solution of leetcode
    github_leetcode_url = 'https://github.com/hey-bruce/algorithms_and_oj/blob/master/leetcode-algorithms/'
    # solution of pat,  I haven't written it yet
    github_pat_url = 'https://github.com/hey-bruce/algorithms_and_oj/blob/master/pat-algorithms/'
    leetcode_url = 'https://leetcode.com/problems/'

class Question:
    """ this class used to store the inform of every question """

    def __init__(self, id_, name, url, lock, difficulty):
        self.id_ = id_
        self.title = name
        # the problem description url  Problem description page
        self.url = url
        self.lock = lock  # Boolean, locked means need to buy
        self.difficulty = difficulty
        # the solution url
        self.python = ' '
        self.java = ' '
        self.javascript = ' '
        self.c_plus_plus = ' '

    def __repr__(self):
        Return: """ """ "
        return str(self.id_) + ' ' + str(self.title) + ' ' + str(self.url)

class TableInform:
    def __init__(self):
        # raw questions inform
        self.questions = []
        # this is table index
        self.table = []
        # this is the element of question
        self.table_item = {}
        self.locked = 0

    def get_leetcode_problems(self):
        """ used to get leetcode inform :return: """
        # we should look the response data carefully to find law
        # return byte. content type is byte
        content = requests.get('https://leetcode.com/api/problems/algorithms/').content
        # get all problems
        self.questions = json.loads(content)['stat_status_pairs']
        # print(self.questions)
        difficultys = ['Easy'.'Medium'.'Hard']
        for i in range(len(self.questions) - 1.- 1.- 1):
            question = self.questions[i]
            name = question['stat'] ['question__title']
            url = question['stat'] ['question__title_slug']
            id_ = str(question['stat'] ['frontend_question_id'])
            if int(id_) < 10:
                id_ = '00' + id_
            elif int(id_) < 100:
                id_ = '0' + id_
            lock = question['paid_only']
            if lock:
                self.locked += 1
            difficulty = difficultys[question['difficulty'] ['level'] - 1]
            url = Config.leetcode_url + url + '/description/'
            q = Question(id_, name, url, lock, difficulty)
            self.table.append(q.id_)
            self.table_item[q.id_] = q
        return self.table, self.table_item

    # create problems folders
    def __create_folder(self, oj_name):
        oj_algorithms = Config.local_path + '/' + oj_name + '-algorithms'
        if os.path.exists(oj_algorithms):
            print(oj_name, ' algorithms is already exits')
        else:
            print('creating {} algorithms.... '.format(oj_name))
            os.mkdir(oj_algorithms)
        for item in self.table_item.values():
            question_folder_name = oj_algorithms + '/' + item.id_ + '. ' + item.title
            if not os.path.exists(question_folder_name):
                print(question_folder_name + 'is not exits, create it now.... ')
                os.mkdir(question_folder_name)

    def update_table(self, oj):
        # the complete inform should be update
        complete_info = CompleteInform()
        self.get_leetcode_problems()
        # the total problem nums
        complete_info.total = len(self.table)
        complete_info.lock = self.locked
        self.__create_folder(oj)
        oj_algorithms = Config.local_path + '/' + oj + '-algorithms'
        # Check os.walk to see what exactly is returned
        for _, folders, _ in os.walk(oj_algorithms):
            for folder in folders:
                for _, _, files in os.walk(os.path.join(oj_algorithms, folder)):
                    # print(files)
                    iflen(files) ! =0:
                        complete_info.complete_num += 1
                    for item in files:
                        if item.endswith('.py'):
                          
  complete_info.solved['python'] + =1
                            folder_url = folder.replace(' '."% 20")
                            folder_url = os.path.join(folder_url, item)
                            folder_url = os.path.join(Config.github_leetcode_url, folder_url)
                            self.table_item[folder[:3]].python = '[Python]({})'.format(folder_url)
                        elif item.endswith('.java'):
                            complete_info.solved['java'] + =1
                            folder_url = folder.replace(' '."% 20")
                            folder_url = os.path.join(folder_url, item)
                            folder_url = os.path.join(Config.github_leetcode_url, folder_url)
                            self.table_item[folder[:3]].java = '[Java]({})'.format(folder_url)
                        elif item.endswith('.cpp'):
                            complete_info.solved['c++'] + =1
                            folder_url = folder.replace(' '."% 20")
                            folder_url = os.path.join(folder_url, item)
                            folder_url = os.path.join(Config.github_leetcode_url, folder_url)
                            self.table_item[folder[:3]].c_plus_plus = '[C++]({})'.format(folder_url)
                        elif item.endswith('.js'):
                            complete_info.solved['javascript'] + =1
                            folder_url = folder.replace(' '."% 20")
                            folder_url = os.path.join(folder_url, item)
                            folder_url = os.path.join(Config.github_leetcode_url, folder_url)
                            self.table_item[folder[:3]].javascript = '[JavaScript]({})'.format(folder_url)
        readme = Readme(complete_info.total, 
                        complete_info.complete_num, 
                        complete_info.lock, 
                        complete_info.solved)
        readme.create_leetcode_readme([self.table, self.table_item])
        print('-------the complete inform-------')
        print(complete_info.solved)

class CompleteInform:
    """ this is statistic inform """

    def __init__(self):
        self.solved = {
            'python': 0.'c++': 0.'java': 0.'javascript': 0
        }
        self.complete_num = 0
        self.lock = 0
        self.total = 0

    def __repr__(self):
        return str(self.solved)

class Readme:
    """ generate folder and markdown file update README.md when you finish one problem by some language """

    def __init__(self, total, solved, locked, others):
        """ :param total: Total Problems nums :param solved: Solved Problem nums :param Others: Not yet
        self.total = total
        self.solved = solved
        self.others = others
        self.locked = locked
        self.time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
        self.msg = '# Keep thinking, keep alive\n' \
                   'Until {}, I have solved **{}** / **{}** problems ' \
                   'while **{}** are still locked.' \
                   '\n\nCompletion statistic: ' \
                   '\n1. JavaScript: {javascript} ' \
                   '\n2. Python: {python}' \
                   '\n3. C++: {c++}' \
                   '\n4. Java: {java}' \
                   '\n\nNote: :lock: means you need to buy a book from LeetCode\n'.format(
                    self.time, self.solved, self.total, self.locked, **self.others)

    def create_leetcode_readme(self, table_instance):
        """ create REAdME.md :return: """
        file_path = Config.local_path + '/README.md'
        # write some basic inform about leetcode
        with open(file_path, 'w') as f:
            f.write(self.msg)
            f.write('\n----------------\n')

        with open(file_path, 'a') as f:
            f.write('## LeetCode Solution Table\n')
            f.write('| ID | Title | Difficulty | JavaScript | Python | C++ | Java |\n')
            f.write('| : - : * 7 + '|\n')
            table, table_item = table_instance
            for index in table:
                item = table_item[index]
                if item.lock:
                    _lock = ':lock:'
                else:
                    _lock = ' '
                data = {
                    'id': item.id_,
                    'title': '[] {}, {} {}'.format(item.title, item.url, _lock),
                    'difficulty': item.difficulty,
                    'js': item.javascript if item.javascript else 'To Do'.'python': item.python if item.python else 'To Do'.'c++': item.c_plus_plus if item.c_plus_plus else 'To Do'.'java': item.java if item.java else 'To Do'
                }
                line = '|{id}|{title}|{difficulty}|{js}|{python}|{c++}|{java}|\n'.format(**data)
                f.write(line)
            print('README.md was created..... ')

def main(a):
    table = TableInform()
    table.update_table('leetcode')

if __name__ == '__main__':
    main()
Copy the code

Welcome to star, Happy Coding!

Author: BBruceyuan

Github:github.com/bbruceyuan

Zhihu column: Make some soy sauce

Brief address: make some sauce

Wechat official account: Make some soy sauce

Blog address: bbruceyuan.github. IO

Check out my blog: BBruceyuan for more content