├── LICENSE.md
├── Procfile
├── README.md
├── app.py
├── leetcode.py
├── requirements.txt
├── sampleoutput.png
└── templates
├── home.html
└── readMe.md
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Ansh Gupta
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Procfile:
--------------------------------------------------------------------------------
1 | web: gunicorn app:app
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Leetcode_DSA_Analytics
2 | A python script that would generate a html report based on programming questions done on Leetcode.
3 |
4 | ## Working with it
5 |
6 | https://leetcode-dsa-analytics.herokuapp.com/
7 |
8 | * Click the link
9 | * Enter your Username
10 | * Get the result.
11 |
12 | ## Report Output
13 |
14 |
15 |
16 | 
17 |
--------------------------------------------------------------------------------
/app.py:
--------------------------------------------------------------------------------
1 | from flask import Flask, render_template,request
2 | from leetcode import main_func
3 | app=Flask(__name__)
4 |
5 | @app.route('/', methods=['GET', 'POST'])
6 | def result():
7 | if request.method == 'POST':
8 | user = request.form['uname']
9 | #result = main_func(user)
10 | return render_template('home.html', result=main_func(user))
11 | else:
12 | return render_template('home.html')
13 |
14 | if __name__ == "__main__":
15 | app.run()
--------------------------------------------------------------------------------
/leetcode.py:
--------------------------------------------------------------------------------
1 | '''
2 | Made by: Ansh Gupta
3 | Created on: 01/03/2022;
4 |
5 | '''
6 |
7 | from plotly.subplots import make_subplots
8 | import plotly.express as px
9 | import plotly.offline as pof
10 | import pandas as pd
11 | import warnings
12 | import requests
13 | import subprocess
14 | import json
15 | import sys
16 | import os
17 |
18 | warnings.filterwarnings("ignore")
19 |
20 | def extract_json(dict):
21 | user=dict['user']
22 | opName=dict['opName']
23 | Query=dict['Query']
24 | data={
25 | "operationName": opName,
26 | "variables": {"username":user},
27 | "query": Query
28 | }
29 | header={
30 | "Referer":f"https://leetcode.com/{user}",
31 | 'Content-type':'application/json'
32 |
33 | }
34 | s=requests.session()
35 | s.get("https://leetcode.com/")
36 | header["x-csrftoken"] = s.cookies["csrftoken"]
37 | r = s.post("https://leetcode.com/graphql",json=data,headers=header)
38 | return json.loads(r.text)
39 |
40 | def util(fig):
41 | traces=[]
42 | for trace in range(len(fig['data'])):
43 | traces.append(fig['data'][trace])
44 | return traces
45 |
46 | def main_func(user):
47 | #user=input("Enter your Leetcode User Name: ")
48 | Query="""query skillStats($username: String!) {
49 | matchedUser(username: $username) {
50 | tagProblemCounts {
51 | advanced {
52 | tagName
53 | problemsSolved
54 | }
55 | intermediate {
56 | tagName
57 | problemsSolved
58 | }
59 | fundamental {
60 | tagName
61 | problemsSolved
62 | }
63 | }
64 | }
65 | }"""
66 | json_data1=extract_json({"user":user,"opName":"skillStats","Query":Query})
67 | try:
68 | df_data1 = json_data1['data']['matchedUser']['tagProblemCounts']['intermediate']
69 | df_data2=json_data1['data']['matchedUser']['tagProblemCounts']['fundamental']
70 | df_data3=json_data1['data']['matchedUser']['tagProblemCounts']['advanced']
71 | df_intermediate= pd.DataFrame(df_data1)
72 | df_fundamental= pd.DataFrame(df_data2)
73 | df_advanced= pd.DataFrame(df_data3)
74 | except:
75 | return ("
The user does not exist!
")
76 |
77 | frames=[df_fundamental,df_intermediate,df_advanced]
78 | res=pd.concat(frames,ignore_index=True)
79 | data_structures=['Array','Matrix','String','Stack','Queue','Linked List','Tree','Binary Tree','Hash Table','Graph','Trie','Union Find']
80 | algorithms=['Sorting','Two Pointers','Greedy','Binary Search','Depth-First Search','Breadth-First Search','Recursion','Sliding Window','Backtracking','Dynamic Programming','Divide and Conquer','Topological Sort','Shortest Path']
81 |
82 | if res.empty:
83 | return ("You have not attempted a single question!
")
84 |
85 | # print("Data Received from Leetcode")
86 | data_structure_df=res.loc[res['tagName'].isin(data_structures)]
87 | data_structure_df=data_structure_df.reset_index(drop=True)
88 | data_df=data_structure_df.sort_values(by=['problemsSolved'])
89 |
90 |
91 | data_bar = px.bar(data_df, x="problemsSolved", y="tagName",orientation='h')
92 | radar_data = (px.line_polar(data_df, r='problemsSolved', theta='tagName', line_close=True)).update_traces(fill='toself')
93 | data_pie=(px.pie(data_structure_df,values='problemsSolved',names='tagName')).update_layout(showlegend=False)
94 |
95 | algorithm_df=res.loc[res['tagName'].isin(algorithms)]
96 | algorithm_df=algorithm_df.reset_index(drop=True)
97 | algo_df=algorithm_df.sort_values(by=['problemsSolved'])
98 |
99 | algo_bar = px.bar(algo_df, x="problemsSolved", y="tagName",orientation='h')
100 | algo_radar = (px.line_polar(algo_df, r='problemsSolved', theta='tagName', line_close=True)).update_traces(fill='toself')
101 | algo_pie=(px.pie(algorithm_df,values='problemsSolved',names='tagName')).update_layout(showlegend=False)
102 |
103 |
104 | data_bar_traces=util(data_bar)
105 | data_radar_traces=util(radar_data)
106 | data_pie_traces=util(data_pie)
107 | algo_bar_traces=util(algo_bar)
108 | algo_radar_traces=util(algo_radar)
109 | algo_pie_traces=util(algo_pie)
110 |
111 | data_fig = make_subplots(rows=2, cols=2,specs=[[{"type":"xy"},{"type":"domain"}],[{"type":"polar"},{"type":"domain"}]],subplot_titles=("Number of question done by Data Structure","% of questions done by Data Structures","","Radar Chart showing number of question by Data Structures"))
112 | for trace in data_bar_traces:
113 | data_fig.append_trace(trace,row=1,col=1)
114 | for trace in data_radar_traces:
115 | data_fig.append_trace(trace,row=2,col=1)
116 | for trace in data_pie_traces:
117 | data_fig.append_trace(trace,row=1,col=2)
118 | data_fig.update_layout(height=900,width=1200)
119 | data_graph=pof.plot(data_fig, include_plotlyjs=False, output_type='div')
120 |
121 | algo_fig = make_subplots(rows=2, cols=2,specs=[[{"type":"xy"},{"type":"domain"}],[{"type":"polar"},{"type":"domain"}]],subplot_titles=("Number of question done by Algorithm","% of questions done by Algorithm","","Radar Chart showing number of question by Algorithm"))
122 | for trace in algo_bar_traces:
123 | algo_fig.append_trace(trace,row=1,col=1)
124 | for trace in algo_radar_traces:
125 | algo_fig.append_trace(trace,row=2,col=1)
126 | for trace in algo_pie_traces:
127 | algo_fig.append_trace(trace,row=1,col=2)
128 | algo_fig.update_layout(height=900,width=1200)
129 | algo_graph=pof.plot(algo_fig, include_plotlyjs=False, output_type='div')
130 | #print("Charts created")
131 |
132 | html_report=""
133 | #html_report+=""
134 | html_report+="Data Structure
"
135 | html_report+=data_graph
136 | html_report+="Algorithms
"
137 | html_report+=algo_graph
138 | #html_report+="
"
139 |
140 | return html_report
141 |
142 |
143 |
144 | #hs = open("leetcodereport.html", 'w+')
145 | #hs.write(html_report)
146 | #hs.close()
147 | #print("Report formed")
148 |
149 |
150 |
151 |
152 | #url=os.path.join(os.getcwd(),'leetcodereport.html')
153 | #try:
154 | # os.startfile(url)
155 | #except AttributeError:
156 | # try:
157 | # subprocess.call(['open',url])
158 | # except:
159 | # print("The report is saved here:")
160 | # print(url)
161 | #
162 | '''
163 | Made by: Ansh Gupta
164 | Created on: 01/03/2022;
165 |
166 | '''
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | asgiref==3.5.0
2 | certifi==2021.10.8
3 | charset-normalizer==2.0.12
4 | click==8.0.4
5 | colorama==0.4.4
6 | Flask==2.0.3
7 | idna==3.3
8 | itsdangerous==2.1.0
9 | Jinja2==3.0.3
10 | MarkupSafe==2.1.0
11 | numpy==1.22.2
12 | pandas==1.4.1
13 | plotly==5.6.0
14 | python-dateutil==2.8.2
15 | pytz==2021.3
16 | requests==2.27.1
17 | six==1.16.0
18 | sqlparse==0.4.2
19 | tenacity==8.0.1
20 | tzdata==2021.5
21 | urllib3==1.26.8
22 | Werkzeug==2.0.3
23 | gunicorn
24 |
--------------------------------------------------------------------------------
/sampleoutput.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ansh422/Leetcode_DSA_Analytics/ee98c4f4bd986c7258dcab5a98f519b73223c63f/sampleoutput.png
--------------------------------------------------------------------------------
/templates/home.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Leetcode DSA Report
7 |
8 |
14 |
15 |
16 | Leetcode DSA Analytics
17 |
22 | {{ result | safe }}
23 |
24 |
25 |
--------------------------------------------------------------------------------
/templates/readMe.md:
--------------------------------------------------------------------------------
1 | A simple Home template.
2 |
--------------------------------------------------------------------------------