ladok3 3.6__py3-none-any.whl → 3.7__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of ladok3 might be problematic. Click here for more details.

doc/ltxobj/ladok3.pdf CHANGED
Binary file
ladok3/__init__.py CHANGED
@@ -4170,6 +4170,12 @@ class Student(LadokRemoteData):
4170
4170
  courses = self.__courses
4171
4171
 
4172
4172
  return filter_on_keys(courses, **kwargs)
4173
+ @property
4174
+ def suspensions(self):
4175
+ """
4176
+ The list of the students' suspensions.
4177
+ """
4178
+ return self.ladok.get_student_suspensions_JSON(self.ladok_id)["Avstangning"]
4173
4179
  class CourseInstance(LadokRemoteData):
4174
4180
  """Represents a course instance. Must be constructed from at least
4175
4181
  ladok (a LadokSession object),
@@ -4189,10 +4195,10 @@ class CourseInstance(LadokRemoteData):
4189
4195
 
4190
4196
  self.__code = data.pop("Utbildningskod")
4191
4197
  self.__name = data.pop("Benamning")
4192
- self.__version = data.pop("Versionsnummer")
4198
+ self.__version = data.pop("Versionsnummer", None)
4193
4199
 
4194
- self.__credits = data.pop("Omfattning")
4195
- self.__unit = data.pop("Enhet")
4200
+ self.__credits = data.pop("Omfattning", None)
4201
+ self.__unit = data.pop("Enhet", None)
4196
4202
 
4197
4203
  self.__grade_scale = self.ladok.get_grade_scales(
4198
4204
  id=data.pop("BetygsskalaID"))
@@ -4325,8 +4331,8 @@ class CourseComponent(LadokData):
4325
4331
  else:
4326
4332
  self.__description = description
4327
4333
 
4328
- self.__credits = kwargs.pop("Omfattning")
4329
- self.__unit = kwargs.pop("Enhet")
4334
+ self.__credits = kwargs.pop("Omfattning", None)
4335
+ self.__unit = kwargs.pop("Enhet", None)
4330
4336
 
4331
4337
  ladok = kwargs.pop("ladok")
4332
4338
  grade_scale_id = kwargs.pop("BetygsskalaID")
@@ -4382,7 +4388,7 @@ class CourseRegistration(CourseInstance):
4382
4388
 
4383
4389
  # ett Ladok-ID för kursomgången
4384
4390
  self.__round_id = kwargs.pop("UtbildningstillfalleUID")
4385
- self.__round_code = kwargs.pop("Utbildningstillfalleskod")
4391
+ self.__round_code = kwargs.pop("Utbildningstillfalleskod", None)
4386
4392
 
4387
4393
  dates = kwargs.pop("Studieperiod")
4388
4394
  self.__start = datetime.date.fromisoformat(dates["Startdatum"])
@@ -4409,10 +4415,10 @@ class CourseRegistration(CourseInstance):
4409
4415
  return self.__end
4410
4416
 
4411
4417
  def __str__(self):
4412
- return f"{self.code} {self.round_code} ({self.start}--{self.end})"
4418
+ return f"{self.code} {self.round_code or ''} ({self.start}--{self.end})"
4413
4419
 
4414
4420
  def __repr__(self):
4415
- return f"{self.code}:{self.round_code}:{self.start}--{self.end}"
4421
+ return f"{self.code}:{self.round_code or ''}:{self.start}--{self.end}"
4416
4422
 
4417
4423
  def results(self, /, **kwargs):
4418
4424
  """Returns the student's results on the course, filtered on keywords"""
@@ -4595,6 +4601,10 @@ class CourseResult(LadokRemoteData):
4595
4601
  """Returns True if the grade has been attested in LADOK"""
4596
4602
  return self.__attested
4597
4603
 
4604
+ def __str__(self):
4605
+ return f"{self.component} {self.grade} " \
4606
+ f"{self.date}{'*' if not self.attested else ''}"
4607
+
4598
4608
  def push(self):
4599
4609
  if self.__uid:
4600
4610
  try:
ladok3/ladok3.nw CHANGED
@@ -908,6 +908,24 @@ for course in self.ladok.registrations_JSON(self.ladok_id):
908
908
  @
909
909
 
910
910
 
911
+ \section{Is the student suspended?}
912
+
913
+ We also want to know if a student is suspended or not.
914
+ We can get a list of suspensions for a student.
915
+ However, since suspended students are rare, we haven't found a specimen to
916
+ study; so we simply don't know what the list contains.
917
+ But we can return it nonetheless.
918
+ We never cache this result since we always want the most up-to-date version.
919
+ <<student attribute methods>>=
920
+ @property
921
+ def suspensions(self):
922
+ """
923
+ The list of the students' suspensions.
924
+ """
925
+ return self.ladok.get_student_suspensions_JSON(self.ladok_id)["Avstangning"]
926
+ @
927
+
928
+
911
929
  \chapter{Courses}\label{CourseClasses}
912
930
 
913
931
  We can use the course-related classes as follows.
@@ -1099,15 +1117,20 @@ print(r"\end{minted}")
1099
1117
 
1100
1118
  Now that we have the [[data]] object, we can assign its values to the private
1101
1119
  attributes.
1120
+ We note, however, that some course instances lack both [[Versionsnummer]] and
1121
+ [[Omfattning]].
1122
+ It seems like faux courses are created to document when students go on
1123
+ Exchanges.
1124
+ These faux courses have a name and code, but no credits or version of syllabus.
1102
1125
  <<assign CourseInstance data to private attributes>>=
1103
1126
  self.__education_id = data.pop("UtbildningUID")
1104
1127
 
1105
1128
  self.__code = data.pop("Utbildningskod")
1106
1129
  self.__name = data.pop("Benamning")
1107
- self.__version = data.pop("Versionsnummer")
1130
+ self.__version = data.pop("Versionsnummer", None)
1108
1131
 
1109
- self.__credits = data.pop("Omfattning")
1110
- self.__unit = data.pop("Enhet")
1132
+ self.__credits = data.pop("Omfattning", None)
1133
+ self.__unit = data.pop("Enhet", None)
1111
1134
 
1112
1135
  self.__grade_scale = self.ladok.get_grade_scales(
1113
1136
  id=data.pop("BetygsskalaID"))
@@ -1126,6 +1149,10 @@ else:
1126
1149
  The [[CourseComponent]] class will make the attributes available.
1127
1150
  We specify the most interesting ones and let the [[LadokData]] constructor turn
1128
1151
  the rest into properties as well, so that they are available for the curious.
1152
+
1153
+ Turns out that some course components don't have any credits.
1154
+ This is probably a consequence of being a component in a course with no
1155
+ credits, \eg one of those faux courses to register exchange studies.
1129
1156
  <<classes>>=
1130
1157
  class CourseComponent(LadokData):
1131
1158
  """Represents a course component of a course registration"""
@@ -1148,8 +1175,8 @@ class CourseComponent(LadokData):
1148
1175
  else:
1149
1176
  self.__description = description
1150
1177
 
1151
- self.__credits = kwargs.pop("Omfattning")
1152
- self.__unit = kwargs.pop("Enhet")
1178
+ self.__credits = kwargs.pop("Omfattning", None)
1179
+ self.__unit = kwargs.pop("Enhet", None)
1153
1180
 
1154
1181
  ladok = kwargs.pop("ladok")
1155
1182
  grade_scale_id = kwargs.pop("BetygsskalaID")
@@ -1260,6 +1287,12 @@ def __fetch_participants(self):
1260
1287
  Students register for a course.
1261
1288
  The [[CourseRegistration]] class represents this data from LADOK.
1262
1289
  This is the object that must be used to get results for a student.
1290
+ This object keeps more info than the course instance.
1291
+
1292
+ We note that some registrations lack the \enquote{Utbildningstillfalleskod}
1293
+ attribute.
1294
+ This happens on \enquote{custom courses} like Erasmus exchanges.
1295
+ If that's the case, we use the value [[None]] in its place.
1263
1296
  <<classes>>=
1264
1297
  class CourseRegistration(CourseInstance):
1265
1298
  """Represents a student's participation in a course instance"""
@@ -1268,7 +1301,7 @@ class CourseRegistration(CourseInstance):
1268
1301
 
1269
1302
  # ett Ladok-ID för kursomgången
1270
1303
  self.__round_id = kwargs.pop("UtbildningstillfalleUID")
1271
- self.__round_code = kwargs.pop("Utbildningstillfalleskod")
1304
+ self.__round_code = kwargs.pop("Utbildningstillfalleskod", None)
1272
1305
 
1273
1306
  dates = kwargs.pop("Studieperiod")
1274
1307
  self.__start = datetime.date.fromisoformat(dates["Startdatum"])
@@ -1295,10 +1328,10 @@ class CourseRegistration(CourseInstance):
1295
1328
  return self.__end
1296
1329
 
1297
1330
  def __str__(self):
1298
- return f"{self.code} {self.round_code} ({self.start}--{self.end})"
1331
+ return f"{self.code} {self.round_code or ''} ({self.start}--{self.end})"
1299
1332
 
1300
1333
  def __repr__(self):
1301
- return f"{self.code}:{self.round_code}:{self.start}--{self.end}"
1334
+ return f"{self.code}:{self.round_code or ''}:{self.start}--{self.end}"
1302
1335
 
1303
1336
  def results(self, /, **kwargs):
1304
1337
  """Returns the student's results on the course, filtered on keywords"""
@@ -1444,6 +1477,10 @@ class CourseResult(LadokRemoteData):
1444
1477
  """Returns True if the grade has been attested in LADOK"""
1445
1478
  return self.__attested
1446
1479
 
1480
+ def __str__(self):
1481
+ return f"{self.component} {self.grade} " \
1482
+ f"{self.date}{'*' if not self.attested else ''}"
1483
+
1447
1484
  def push(self):
1448
1485
  if self.__uid:
1449
1486
  <<push the existing CourseResult grade data to LADOK>>
ladok3/student.nw CHANGED
@@ -79,6 +79,7 @@ except Exception as err:
79
79
  print_student_data(student)
80
80
 
81
81
  if args.course:
82
+ print()
82
83
  print_course_data(student, args.course)
83
84
  @
84
85
 
@@ -94,16 +95,20 @@ def print_student_data(student):
94
95
  print(f"Personnummer: {student.personnummer}")
95
96
  print(f"LADOK ID: {student.ladok_id}")
96
97
  print(f"Alive: {student.alive}")
98
+ print(f"Suspended: {student.suspensions}")
97
99
  @
98
100
 
99
101
  \subsection{Printing student's course data}
100
102
 
101
103
  To print the student's course data, we simply filter the courses on the option
102
104
  that the user supplies.
105
+ We then print all results for each course.
103
106
  <<functions>>=
104
107
  def print_course_data(student, course):
105
108
  """Prints the courses"""
106
109
  print("Courses:")
107
110
  for course in student.courses(code=course):
108
- print(f"- {course}")
111
+ print(f"{course}")
112
+ for result in course.results():
113
+ print(f" {result}")
109
114
  @
ladok3/student.py CHANGED
@@ -8,11 +8,14 @@ def print_student_data(student):
8
8
  print(f"Personnummer: {student.personnummer}")
9
9
  print(f"LADOK ID: {student.ladok_id}")
10
10
  print(f"Alive: {student.alive}")
11
+ print(f"Suspended: {student.suspensions}")
11
12
  def print_course_data(student, course):
12
13
  """Prints the courses"""
13
14
  print("Courses:")
14
15
  for course in student.courses(code=course):
15
- print(f"- {course}")
16
+ print(f"{course}")
17
+ for result in course.results():
18
+ print(f" {result}")
16
19
 
17
20
  def add_command_options(parser):
18
21
  student_parser = parser.add_parser("student",
@@ -42,4 +45,5 @@ def command(ladok, args):
42
45
  print_student_data(student)
43
46
 
44
47
  if args.course:
48
+ print()
45
49
  print_course_data(student, args.course)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ladok3
3
- Version: 3.6
3
+ Version: 3.7
4
4
  Summary: Python wrapper and CLI for the LADOK3 REST API.
5
5
  Home-page: https://github.com/dbosk/ladok3
6
6
  License: MIT
@@ -1,7 +1,7 @@
1
- doc/ltxobj/ladok3.pdf,sha256=LlhF8hsKD_CtUqiNccSy6VTg3xNNl54DDh9-zzD0bG8,1320856
1
+ doc/ltxobj/ladok3.pdf,sha256=icIbzJ8YAOai3DhC7XrIMphm7LGkclZHwxGzPl3u_-E,1334876
2
2
  ladok3/.gitignore,sha256=QOcCshtjIsFasi4vaqFcooBWPJkxVWaoYEWOBBtdY_w,81
3
3
  ladok3/Makefile,sha256=Jy6OFjoVLU9YivnVxctxI_zrUOK9ysEOiistJ3ST6Nw,557
4
- ladok3/__init__.py,sha256=I7O5jFFAlco4rHmgUzJoHq_nZ-MhTVwE5n03s8ikZvE,228517
4
+ ladok3/__init__.py,sha256=bdFgx0CHaosa5hDqmLbIGjq6IoVHkXqO--yaIpuOOGU,228872
5
5
  ladok3/api.nw,sha256=xCPoCQRMgvChbep_l6PFS9c-Ua4NpdK_cgcWr_diizc,43238
6
6
  ladok3/cli.nw,sha256=na0B80ll4Ocz7jOYj6ztehCHlPasPB212d6m_4LBOmk,20472
7
7
  ladok3/cli.py,sha256=8qZGIxGQ4WLOciZIRf34bGvU0KS9pFyr0zUymuoSCA8,10321
@@ -9,15 +9,15 @@ ladok3/data.nw,sha256=3o6-kmeMtCGoSJ5yL8qFCuIINQeym_WtW_2mhItuR-s,11785
9
9
  ladok3/data.py,sha256=mCHySFtQL_oh6mkfMbgRM4T1bnM8HR45eumgoKFwomk,5893
10
10
  ladok3/kth.py,sha256=aoodYd2bLQcPNQiFwyP0mppJO399UcqUgUhN9wzVwBA,3720
11
11
  ladok3/ladok.bash,sha256=zGfTFdtos2zLjV13pzfK-1uCy2b_lF2qUKMoL2ExW7c,1441
12
- ladok3/ladok3.nw,sha256=iWeQwilaGL1y_b9EF8rFANm5wvw5wNaKtOnx4Af1LkE,48653
12
+ ladok3/ladok3.nw,sha256=UoiEJAIihPNrHuMHWjoNoz7pl2hDEkziGE3B6X6zbk0,50144
13
13
  ladok3/report.nw,sha256=_PUV9Qrg1aUuxiqcQg3VNOApOY3oDdTEJSCOdRiluyc,7303
14
14
  ladok3/report.py,sha256=rNCIiPTd9egw8iXSSKsmyrcF3NebqinpuRxfphcyIjo,4082
15
- ladok3/student.nw,sha256=7ErLwgyAVjzwDn6sqBf7bUXxl1EuQkjMaZUBfQxg9JU,3194
16
- ladok3/student.py,sha256=qO7-MLoCeYcvhvRsy7EnINXeyHPiCod7yAGpnLRI6VE,1410
15
+ ladok3/student.nw,sha256=RFS3Uo-l_dYsmm41Psh4EPO3LpJQ2ipDSLBsFhlkTco,3356
16
+ ladok3/student.py,sha256=3YRf6WXimFBusH-sBiWKJhEJ_W-qfzqVPox2sLJNFCI,1531
17
17
  ladok3/test.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
18
  ladok3/undoc.nw,sha256=NyHuVIzrRqJPM39MyAlZNEE7PbXdUDJFQ2kJ0NfdwQI,180333
19
- ladok3-3.6.dist-info/LICENSE,sha256=s_C5qznXAvDRrzU7vRd4eqzshyIkAfPwGyVBihGeOdM,1155
20
- ladok3-3.6.dist-info/METADATA,sha256=4N5XD6hdyuwWz3cUIjFF5awQ5x7aOyIalXQLRfdcV3o,8098
21
- ladok3-3.6.dist-info/WHEEL,sha256=kLuE8m1WYU0Ig0_YEGrXyTtiJvKPpLpDEiChiNyei5Y,88
22
- ladok3-3.6.dist-info/entry_points.txt,sha256=pi-KKP5Obo0AyuDjXQUpadS9kIvAY2_5ORhPgEYlJv8,41
23
- ladok3-3.6.dist-info/RECORD,,
19
+ ladok3-3.7.dist-info/LICENSE,sha256=s_C5qznXAvDRrzU7vRd4eqzshyIkAfPwGyVBihGeOdM,1155
20
+ ladok3-3.7.dist-info/METADATA,sha256=Jelc3ichBPu0MfSaO58NbteMHOAuenpMG4Z6-X95NEc,8098
21
+ ladok3-3.7.dist-info/WHEEL,sha256=kLuE8m1WYU0Ig0_YEGrXyTtiJvKPpLpDEiChiNyei5Y,88
22
+ ladok3-3.7.dist-info/entry_points.txt,sha256=pi-KKP5Obo0AyuDjXQUpadS9kIvAY2_5ORhPgEYlJv8,41
23
+ ladok3-3.7.dist-info/RECORD,,
File without changes
File without changes