@@ -78,6 +78,9 @@ class User(db.Model):
78
78
time_multiplier : int = db .Column (
79
79
db .Integer , default = 1 , server_default = "1" , nullable = False
80
80
) # user time multiplier
81
+ rating : float = db .Column (
82
+ db .Float , default = 0 , server_default = "0" , nullable = False
83
+ ) # user rating score
81
84
82
85
def add_xp (self , amount : float ) -> None : # add XP
83
86
"""
@@ -348,6 +351,9 @@ def complete_task(task_id) -> Response: # complete task from task ID
348
351
active_tasks : int = Task .query .filter_by (
349
352
completed = False
350
353
).count () # get number of active tasks (tasks that are not completed)
354
+ overdue_tasks : int = Task .query .filter (
355
+ Task .due_date < date .today ()
356
+ ).count () # get number of overdue tasks (due date is before today)
351
357
if user is not None : # if user exists
352
358
user .tasks_completed += 1 # increase the number of tasks completed by 1
353
359
day_difference : timedelta = datetime .now () - datetime (
@@ -380,6 +386,21 @@ def complete_task(task_id) -> Response: # complete task from task ID
380
386
user .combo_multiplier += 1 # increase combo multipler by 1
381
387
else :
382
388
user .combo_multiplier = 0 # reset combo multiplier to 0
389
+ if day_difference .days >= 1 : # check if at least 1 day of inactivity
390
+ for i in range (
391
+ day_difference .days
392
+ ): # repeat for each day of inactivity
393
+ user .rating -= max (
394
+ (
395
+ math .sqrt (max (user .rating , 0 ))
396
+ * (1 + math .log (max (i + 1 , 1 )))
397
+ * (1 + math .log (max .max (overdue_tasks + 1 , 1 )))
398
+ ),
399
+ 0 ,
400
+ ) # decrease the user rating score for each day of inactivity
401
+ user .rating = max (
402
+ user .rating , 0
403
+ ) # make sure the user rating score is not below 0
383
404
user .last_task_completed = (
384
405
task .id
385
406
) # set user last task completed to task ID
@@ -405,25 +426,41 @@ def complete_task(task_id) -> Response: # complete task from task ID
405
426
user .last_time_clicked = (
406
427
current_time # set last time clicked to current time
407
428
)
429
+ user .rating += max (
430
+ (
431
+ (10 + math .log (max (user .rating + 100 , 100 )) ** 2 )
432
+ * repeat_multiplier
433
+ * (1 - date_multiplier )
434
+ if date_multiplier < 1
435
+ else (date_multiplier - 1 ) / max (user .daily_tasks_completed , 1 )
436
+ ),
437
+ 0 ,
438
+ ) # increase user rating score based on user rating, task repeat multiplier and number of tasks completed today
439
+ user .rating = max (
440
+ user .rating , 0
441
+ ) # make sure the user rating score is not below 0
408
442
user .add_xp (
409
443
round (
410
- task .priority
411
- * task .difficulty
412
- * task .repeat_often
413
- * repeat_multiplier
414
- * (1 + math .log (max (task .times_completed , 1 )))
415
- * (1 + math .log (max (user .tasks_completed , 1 )))
416
- * (1 + math .log (max (active_tasks , 1 )))
417
- * (1 + user .daily_streak / 10 )
418
- * (1 + user .daily_tasks_completed / 10 )
419
- * (1 + math .log (max (user .days_completed , 1 )))
420
- * (1 + task .streak / 10 )
421
- * due_multiplier
422
- * (1 + user .combo_multiplier / 10 )
423
- * user .time_multiplier
424
- * (1 + 5.0 / (abs (time_difference_seconds ) + 1.0 ))
444
+ (
445
+ task .priority
446
+ * task .difficulty
447
+ * task .repeat_often
448
+ * repeat_multiplier
449
+ * (1 + math .log (max (task .times_completed , 1 )))
450
+ * (1 + math .log (max (user .tasks_completed , 1 )))
451
+ * (1 + math .log (max (active_tasks , 1 )))
452
+ * (1 + user .daily_streak / 10 )
453
+ * (1 + user .daily_tasks_completed / 10 )
454
+ * (1 + math .log (max (user .days_completed , 1 )))
455
+ * (1 + task .streak / 10 )
456
+ * due_multiplier
457
+ * (1 + user .combo_multiplier / 10 )
458
+ * user .time_multiplier
459
+ * (1 + 5.0 / (abs (time_difference_seconds ) + 1.0 ))
460
+ + user .combo_multiplier
461
+ )
462
+ * (1 + math .log (max (user .rating + 1 , 1 )))
425
463
)
426
- + user .combo_multiplier
427
464
) # add XP
428
465
db .session .commit () # commit database changes
429
466
return redirect (url_for ("index" )) # redirect to index page template
@@ -567,6 +604,12 @@ def init_db() -> None: # initialize database
567
604
"ALTER TABLE user ADD COLUMN time_multiplier INT NOT NULL DEFAULT 1"
568
605
)
569
606
) # create time multipler column
607
+ if "rating" not in [
608
+ column ["name" ] for column in db .inspect (db .engine ).get_columns ("user" )
609
+ ]: # check if rating score column is not in the user table
610
+ db .session .execute (
611
+ text ("ALTER TABLE user ADD COLUMN rating FLOAT NOT NULL DEFAULT 0" )
612
+ ) # create rating score column
570
613
if User .query .count () == 0 : # if there are no users
571
614
new_user = User (username = "Player" ) # create new user
572
615
db .session .add (new_user ) # add new user to the database
0 commit comments