Skip to content

Commit 7364fee

Browse files
committed
finished proj
0 parents  commit 7364fee

File tree

7 files changed

+531
-0
lines changed

7 files changed

+531
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
__pycache__

README.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Transcript Generator
2+
3+
A web client that generates transcripts of students via parsing data from specific files and makes it available to download as zip.
4+
* Generation of transcript in specified range of roll numbers is supported!
5+
6+
## Running the website
7+
* Run `python3 coreLogic.py` and the server will start at the shown port

assets/instiLogo.jpeg

22.2 KB
Loading

assets/tsBanner.png

81.3 KB
Loading

coreLogic.py

+312
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,312 @@
1+
from fpdf import FPDF
2+
from datetime import datetime
3+
import shutil
4+
import pandas as pd
5+
import csv
6+
import os
7+
8+
baseDir = os.path.join(os.getcwd(), "assets")
9+
file_to_be_parsed = os.path.join(os.getcwd(), "uploads/grades.csv")
10+
subNameMapping = os.path.join(os.getcwd(), "uploads/subjects_master.csv")
11+
studNameMapping = os.path.join(os.getcwd(), "uploads/names-roll.csv")
12+
13+
masterList = []
14+
studNameMap = {}
15+
dfl = {}
16+
dct = {}
17+
18+
branchMap = {
19+
"CS": "Computer Science and Engineering",
20+
"CB": "Chemical Engineering",
21+
"EE": "Electrical & Electronics Engineering",
22+
"ME": "Mechanical Engineering",
23+
"MM": "Metallurgical Engineering",
24+
"CE": "Civil Engineering",
25+
"CH": "Chemistry",
26+
}
27+
28+
gradeMap = {
29+
"AA": 10,
30+
"AB": 9,
31+
"BB": 8,
32+
"BC": 7,
33+
"CC": 6,
34+
"CD": 5,
35+
"DD": 4,
36+
"F": 0,
37+
"I": 0,
38+
}
39+
40+
41+
def prepLists():
42+
for ind, line in enumerate(csv.reader(open(studNameMapping))):
43+
if ind > 0:
44+
studNameMap[line[0]] = line[1]
45+
46+
def fixWildcardEntry(grade) -> str:
47+
return grade.replace("*", "") if grade[len(grade) - 1] == "*" else grade
48+
49+
50+
def prepOverallResult(rollNum: str):
51+
spi, cpi = ["SPI"], ["CPI"]
52+
53+
masterList = []
54+
for ind, line in enumerate(csv.reader(open(file_to_be_parsed))):
55+
masterList.append(line)
56+
57+
maxSem = 0
58+
59+
# Find max sems for a roll no
60+
for ind, line in enumerate(masterList):
61+
if line[0] == rollNum:
62+
maxSem = max(maxSem, int(line[1]))
63+
maxSem += 1 # As range iterates till maxValue - 1
64+
65+
semwiseCreds = ["Semester wise Credit Taken"]
66+
fullCreds = ["Total Credits Taken"]
67+
clearedCreds = ["Total Credits Cleared"]
68+
semRow = ["Semester No", 1]
69+
70+
for f in range(1, maxSem):
71+
ms, cls, spis = 0, 0, 0
72+
for ind, line in enumerate(masterList):
73+
if ind > 0:
74+
if line[0] == rollNum: # Fix a roll no
75+
if int(line[1]) == f: # Iterate on a specific sem
76+
ms += int(line[3])
77+
finalGrade = fixWildcardEntry(line[4].strip())
78+
if finalGrade == "F" or finalGrade == "I":
79+
pass
80+
else:
81+
cls += int(line[3])
82+
spis += int(line[3]) * gradeMap[finalGrade]
83+
84+
# Handle the case for the sem which does not exist
85+
mSemWiseClsCreds = cls
86+
mSpi = 0
87+
mSemWiseCreds = 0
88+
if ms > 0:
89+
mSpi = (spis / ms).__round__(2)
90+
mSemWiseCreds = ms
91+
spi.append(mSpi)
92+
semwiseCreds.append(mSemWiseCreds)
93+
clearedCreds.append(mSemWiseClsCreds)
94+
95+
mCpi = spi[1] * semwiseCreds[1]
96+
dynCreds = semwiseCreds[1]
97+
fullCreds.append(dynCreds)
98+
cpi.append(spi[1]) # Because CPI in 1st sem is same as SPI in 1st sem
99+
100+
for sem in range(2, maxSem):
101+
semRow.append(sem)
102+
dynCreds += semwiseCreds[sem]
103+
fullCreds.append(dynCreds)
104+
mCpi += spi[sem] * semwiseCreds[sem]
105+
cpi.append((mCpi / dynCreds).__round__(2))
106+
107+
return maxSem - 1, semwiseCreds, clearedCreds, spi, cpi
108+
109+
def checkForImg(imgName) -> bool:
110+
conts = os.listdir(os.path.join(os.getcwd(), "uploads"))
111+
if imgName not in conts:
112+
return False
113+
return True
114+
115+
def prepPdfForRolls(rng: []):
116+
sealAv = checkForImg("seal.jpeg")
117+
signAv = checkForImg("sign.jpeg")
118+
for roll in rng:
119+
dims = {}
120+
stdims = {}
121+
txtForSem = {}
122+
missed = 0
123+
if roll in dfl:
124+
sems, swcreds, clsCreds, spiz, cpiz = prepOverallResult(roll)
125+
pdf = FPDF(orientation="L", unit="mm", format="A3")
126+
pdf.add_page()
127+
pdf.set_font("Times", size=8.5)
128+
line_height = pdf.font_size * 1.5
129+
pdf.rect(x=10, y=10, w=pdf.w - 20, h=pdf.h-20, style="")
130+
pdf.rect(x=85, y=43, w=(pdf.w / 2) + 20, h=15, style="")
131+
fmtr = 0
132+
pdf.image(os.path.join(os.getcwd(), "assets/tsBanner.png"), x=10, y=10, w=pdf.w - 20)
133+
prg = ""
134+
temp = roll
135+
if str(temp)[2] == '1':
136+
prg = "Master of Technology"
137+
if str(temp)[2] == '2':
138+
prg = "PhD"
139+
if str(temp)[2] == '0':
140+
prg = "Bachelor of Technology"
141+
pdf.set_font(size=12, style="B")
142+
pdf.text(x=87, y=48, txt=f"Roll No: {roll} Name: {studNameMap[roll]} Year of Admission: 20{roll[0] + roll[1]}")
143+
pdf.text(x=87, y=55, txt=f"Programme: {prg} Course: {branchMap[str(temp[4] + temp[5])]}")
144+
145+
pdf.set_font(size=10, style="")
146+
abscissa = 7
147+
ordinate = 64
148+
recy = 0
149+
recx = 0
150+
tx = 7
151+
pdf.set_y(ordinate+5)
152+
153+
for sem in range(sems):
154+
indx = 0
155+
if (sem) % 4 == 0 and sem > 0:
156+
pdf.set_x(recx)
157+
if sem + 1 in dfl[roll].keys():
158+
for info in dfl[roll][sem + 1]:
159+
if abscissa != 0:
160+
pdf.set_x(abscissa + 8)
161+
rind = 0
162+
wdh = 0
163+
ls = len(info) + 1
164+
for ir in range(ls):
165+
if rind == 0:
166+
wdh = 14
167+
elif rind == 1:
168+
wdh = 75
169+
elif rind == 2:
170+
wdh = 13
171+
elif rind == 4 or rind == 3:
172+
wdh = 11
173+
174+
if indx == 0:
175+
pdf.set_font(style="B")
176+
else:
177+
pdf.set_font(style="")
178+
if ir < ls - 1:
179+
if sem not in stdims:
180+
stdims[sem] = []
181+
stdims[sem] = [pdf.get_x(), pdf.get_y()]
182+
pdf.set_font(style="BU", size=10)
183+
pdf.text(x=stdims[sem][0], y=stdims[sem][1] - 1, txt=f"Semester {sem + 1}")
184+
pdf.set_font(style="")
185+
pdf.set_xy(x=stdims[sem][0], y=stdims[sem][1])
186+
pdf.multi_cell(wdh, line_height, str(info[ir]), border=1, ln=3, max_line_height=pdf.font_size, align="C")
187+
rind += 1
188+
if indx == (len(dfl[roll][sem + 1]) - 1):
189+
if sem not in dims:
190+
dims[sem] = []
191+
dims[sem] = [pdf.get_x().__round__(2), pdf.get_y().__round__(2)]
192+
abscissa = pdf.get_x()
193+
tx = pdf.get_x()
194+
if (sem + 1) % 3 == 0:
195+
recy = pdf.get_y() + 22.5
196+
abscissa = 7
197+
recx = abscissa
198+
cx, cy = pdf.get_x() - 110, pdf.get_y() + 8
199+
pdf.set_font(style="B", size=10)
200+
pdf.text(x=cx - 12, y= cy + 2, txt=f"Total Credits: {str(swcreds[sem + 1])} Credits cleared: {str(clsCreds[sem + 1])} SPI: {str(spiz[sem + 1])} CPI: {str(cpiz[sem + 1])}")
201+
pdf.rect(x=cx - 14, y=cy - 2, w=94, h=5.6, style="")
202+
pdf.set_font(style="", size=9)
203+
ah = recy if recy > 0 else ordinate
204+
pdf.set_y(ah)
205+
ordinate = pdf.get_y()
206+
indx += 1
207+
pdf.ln(line_height)
208+
else:
209+
missed += 1
210+
continue
211+
ldims = len(dims) - missed - 1
212+
if signAv:
213+
pdf.image(os.path.join(os.getcwd(), "uploads/sign.jpeg"), x=pdf.w-65, y=dims[ldims][1] + 37, w=40)
214+
if sealAv:
215+
pdf.image(os.path.join(os.getcwd(), "uploads/seal.jpeg"), x=(pdf.w - 20)/2, y=dims[ldims][1] + 27, w=40)
216+
pdf.line(x1=10, y1=dims[ldims][1] + 30, x2= pdf.w - 10, y2=dims[ldims][1] + 28)
217+
218+
xco = dims[ldims][0] + 80
219+
yco = dims[ldims][1] + 50
220+
pdf.line(xco, yco, xco + 50, yco)
221+
pdf.set_font(size=14, style="B")
222+
pdf.text(xco - 42, yco, txt="Assitant Registrar")
223+
pdf.text(20, yco, txt=f"Date Generated: {datetime.today().strftime('%d-%m-%Y | %H:%M:%S')}")
224+
pdf.output(f"transcriptsIITP/{roll}.pdf")
225+
else:
226+
continue
227+
return
228+
229+
230+
def prepMs(rnz, all=False):
231+
temp = rnz.replace(" ", "").split("-")
232+
233+
validRange = []
234+
absValidRange = []
235+
invzRolls = []
236+
lulz = False
237+
238+
if not all:
239+
if len(temp) == 1:
240+
return False, []
241+
242+
for f in range(7):
243+
if temp[1][f] != temp[1][f]:
244+
lulz = True
245+
return False, []
246+
247+
if not lulz:
248+
start = int(temp[0][-2:])
249+
end = int(temp[1][-2:]) + 1
250+
251+
for num in range(start, end):
252+
tempo = f"{num}"
253+
if len(str(num)) == 1:
254+
tempo = f"0{num}"
255+
validRange.append(f"{temp[0][:6]}{tempo}")
256+
257+
if os.path.exists(os.path.join(os.getcwd(), "transcriptsIITP")):
258+
shutil.rmtree(os.path.join(os.getcwd(), "transcriptsIITP"))
259+
os.mkdir(os.path.join(os.getcwd(), "transcriptsIITP"))
260+
261+
prepLists()
262+
somethingAns = pd.read_csv(file_to_be_parsed)
263+
dFrame = pd.read_csv(file_to_be_parsed, usecols=[0, 1, 2, 3, 4, 5], index_col=0)
264+
dFrame.sort_values(by=["Roll", "Sem", "SubCode"], inplace=True)
265+
266+
cntr = 1
267+
268+
for index, contents in enumerate(csv.reader(open(subNameMapping))):
269+
if index > 1:
270+
for ind in contents:
271+
dct[contents[0]] = [contents[1], contents[2]]
272+
273+
for index, line in dFrame.iterrows():
274+
if index not in dfl:
275+
dfl[index] = {}
276+
if line[0] not in dfl[index]:
277+
dfl[index][line[0]] = []
278+
dfl[index][line[0]].append(["Sub", "Course Name", "L-T-P", "CRD", "GRD"])
279+
dfl[index][line[0]].append(
280+
[line[1], dct[line[1]][0], dct[line[1]][1], line[2], line[3]]
281+
)
282+
if all and (rnz.strip(" ") == ""):
283+
absValidRange.append(index)
284+
285+
if not all:
286+
for sth in validRange:
287+
if sth in dfl:
288+
absValidRange.append(sth)
289+
else:
290+
invzRolls.append(sth)
291+
292+
prepPdfForRolls(absValidRange)
293+
# prepareTranscriptsArchive()
294+
dfl.clear()
295+
return True, invzRolls
296+
297+
def prepareTranscriptsArchive():
298+
if os.path.exists(os.path.join(os.getcwd(), "transcriptsIITP")):
299+
if len(os.listdir(os.path.join(os.getcwd(), "transcriptsIITP"))) > 0:
300+
shutil.make_archive("transcripts", "zip", os.path.join(os.getcwd(), "transcriptsIITP"))
301+
return True
302+
return False
303+
else:
304+
return False
305+
306+
def main():
307+
#prepMs("1901CS01-1901CS04")
308+
#print("done")
309+
pass
310+
311+
if __name__ == "__main__":
312+
main()

0 commit comments

Comments
 (0)