@@ -220,3 +220,139 @@ class ProjectEvaluationScore(models.Model):
220220
221221 def __str__ (self ):
222222 return f"Score: { self .score } for submission by { self .submission .id } "
223+
224+
225+ class ProjectStatistics (models .Model ):
226+ project = models .OneToOneField (
227+ Project , on_delete = models .CASCADE , related_name = "statistics"
228+ )
229+
230+ total_submissions = models .IntegerField (default = 0 )
231+
232+ # Fields for project_score
233+ min_project_score = models .IntegerField (null = True , blank = True )
234+ max_project_score = models .IntegerField (null = True , blank = True )
235+ avg_project_score = models .FloatField (null = True , blank = True )
236+ median_project_score = models .FloatField (null = True , blank = True )
237+ q1_project_score = models .FloatField (null = True , blank = True )
238+ q3_project_score = models .FloatField (null = True , blank = True )
239+
240+ # Fields for project_learning_in_public_score
241+ min_project_learning_in_public_score = models .IntegerField (null = True , blank = True )
242+ max_project_learning_in_public_score = models .IntegerField (null = True , blank = True )
243+ avg_project_learning_in_public_score = models .FloatField (null = True , blank = True )
244+ median_project_learning_in_public_score = models .FloatField (null = True , blank = True )
245+ q1_project_learning_in_public_score = models .FloatField (null = True , blank = True )
246+ q3_project_learning_in_public_score = models .FloatField (null = True , blank = True )
247+
248+ # Fields for peer_review_score
249+ min_peer_review_score = models .IntegerField (null = True , blank = True )
250+ max_peer_review_score = models .IntegerField (null = True , blank = True )
251+ avg_peer_review_score = models .FloatField (null = True , blank = True )
252+ median_peer_review_score = models .FloatField (null = True , blank = True )
253+ q1_peer_review_score = models .FloatField (null = True , blank = True )
254+ q3_peer_review_score = models .FloatField (null = True , blank = True )
255+
256+ # Fields for peer_review_learning_in_public_score
257+ min_peer_review_learning_in_public_score = models .IntegerField (null = True , blank = True )
258+ max_peer_review_learning_in_public_score = models .IntegerField (null = True , blank = True )
259+ avg_peer_review_learning_in_public_score = models .FloatField (null = True , blank = True )
260+ median_peer_review_learning_in_public_score = models .FloatField (null = True , blank = True )
261+ q1_peer_review_learning_in_public_score = models .FloatField (null = True , blank = True )
262+ q3_peer_review_learning_in_public_score = models .FloatField (null = True , blank = True )
263+
264+ # Fields for total_score
265+ min_total_score = models .IntegerField (null = True , blank = True )
266+ max_total_score = models .IntegerField (null = True , blank = True )
267+ avg_total_score = models .FloatField (null = True , blank = True )
268+ median_total_score = models .FloatField (null = True , blank = True )
269+ q1_total_score = models .FloatField (null = True , blank = True )
270+ q3_total_score = models .FloatField (null = True , blank = True )
271+
272+ # Fields for time_spent
273+ min_time_spent = models .FloatField (null = True , blank = True )
274+ max_time_spent = models .FloatField (null = True , blank = True )
275+ avg_time_spent = models .FloatField (null = True , blank = True )
276+ median_time_spent = models .FloatField (null = True , blank = True )
277+ q1_time_spent = models .FloatField (null = True , blank = True )
278+ q3_time_spent = models .FloatField (null = True , blank = True )
279+
280+ last_calculated = models .DateTimeField (auto_now = True )
281+
282+ def get_value (self , field_name , stats_type ):
283+ attribute_name = f"{ stats_type } _{ field_name } "
284+ return getattr (self , attribute_name )
285+
286+ def get_stat_fields (self ):
287+ results = []
288+
289+ results .append (
290+ ("Project score" , [
291+ (self .min_project_score , "Minimum" , "fas fa-arrow-down" ),
292+ (self .max_project_score , "Maximum" , "fas fa-arrow-up" ),
293+ (self .avg_project_score , "Average" , "fas fa-equals" ),
294+ (self .q1_project_score , "25th Percentile" , "fas fa-percentage" ),
295+ (self .median_project_score , "Median" , "fas fa-percentage" ),
296+ (self .q3_project_score , "75th Percentile" , "fas fa-percentage" ),
297+ ], 'fas fa-project-diagram' )
298+ )
299+
300+ results .append (
301+ ("Project learning in public score" , [
302+ (self .min_project_learning_in_public_score , "Minimum" , "fas fa-arrow-down" ),
303+ (self .max_project_learning_in_public_score , "Maximum" , "fas fa-arrow-up" ),
304+ (self .avg_project_learning_in_public_score , "Average" , "fas fa-equals" ),
305+ (self .q1_project_learning_in_public_score , "25th Percentile" , "fas fa-percentage" ),
306+ (self .median_project_learning_in_public_score , "Median" , "fas fa-percentage" ),
307+ (self .q3_project_learning_in_public_score , "75th Percentile" , "fas fa-percentage" ),
308+ ], 'fas fa-globe' )
309+ )
310+
311+ results .append (
312+ ("Peer review score" , [
313+ (self .min_peer_review_score , "Minimum" , "fas fa-arrow-down" ),
314+ (self .max_peer_review_score , "Maximum" , "fas fa-arrow-up" ),
315+ (self .avg_peer_review_score , "Average" , "fas fa-equals" ),
316+ (self .q1_peer_review_score , "25th Percentile" , "fas fa-percentage" ),
317+ (self .median_peer_review_score , "Median" , "fas fa-percentage" ),
318+ (self .q3_peer_review_score , "75th Percentile" , "fas fa-percentage" ),
319+ ], 'fas fa-users' )
320+ )
321+
322+ results .append (
323+ ("Peer review learning in public score" , [
324+ (self .min_peer_review_learning_in_public_score , "Minimum" , "fas fa-arrow-down" ),
325+ (self .max_peer_review_learning_in_public_score , "Maximum" , "fas fa-arrow-up" ),
326+ (self .avg_peer_review_learning_in_public_score , "Average" , "fas fa-equals" ),
327+ (self .q1_peer_review_learning_in_public_score , "25th Percentile" , "fas fa-percentage" ),
328+ (self .median_peer_review_learning_in_public_score , "Median" , "fas fa-percentage" ),
329+ (self .q3_peer_review_learning_in_public_score , "75th Percentile" , "fas fa-percentage" ),
330+ ], 'fas fa-share-alt' )
331+ )
332+
333+ results .append (
334+ ("Total score" , [
335+ (self .min_total_score , "Minimum" , "fas fa-arrow-down" ),
336+ (self .max_total_score , "Maximum" , "fas fa-arrow-up" ),
337+ (self .avg_total_score , "Average" , "fas fa-equals" ),
338+ (self .q1_total_score , "25th Percentile" , "fas fa-percentage" ),
339+ (self .median_total_score , "Median" , "fas fa-percentage" ),
340+ (self .q3_total_score , "75th Percentile" , "fas fa-percentage" ),
341+ ], 'fas fa-star' )
342+ )
343+
344+ results .append (
345+ ("Time spent on project" , [
346+ (self .min_time_spent , "Minimum" , "fas fa-arrow-down" ),
347+ (self .max_time_spent , "Maximum" , "fas fa-arrow-up" ),
348+ (self .avg_time_spent , "Average" , "fas fa-equals" ),
349+ (self .q1_time_spent , "25th Percentile" , "fas fa-percentage" ),
350+ (self .median_time_spent , "Median" , "fas fa-percentage" ),
351+ (self .q3_time_spent , "75th Percentile" , "fas fa-percentage" ),
352+ ], 'fas fa-clock' )
353+ )
354+
355+ return results
356+
357+ def __str__ (self ):
358+ return f"Statistics for { self .project .slug } "
0 commit comments