@@ -78,6 +78,9 @@ class User(db.Model):
7878 time_multiplier : int = db .Column (
7979 db .Integer , default = 1 , server_default = "1" , nullable = False
8080 ) # user time multiplier
81+ rating : float = db .Column (
82+ db .Float , default = 0 , server_default = "0" , nullable = False
83+ ) # user rating score
8184
8285 def add_xp (self , amount : float ) -> None : # add XP
8386 """
@@ -348,6 +351,9 @@ def complete_task(task_id) -> Response: # complete task from task ID
348351 active_tasks : int = Task .query .filter_by (
349352 completed = False
350353 ).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)
351357 if user is not None : # if user exists
352358 user .tasks_completed += 1 # increase the number of tasks completed by 1
353359 day_difference : timedelta = datetime .now () - datetime (
@@ -380,6 +386,21 @@ def complete_task(task_id) -> Response: # complete task from task ID
380386 user .combo_multiplier += 1 # increase combo multipler by 1
381387 else :
382388 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
383404 user .last_task_completed = (
384405 task .id
385406 ) # set user last task completed to task ID
@@ -405,25 +426,41 @@ def complete_task(task_id) -> Response: # complete task from task ID
405426 user .last_time_clicked = (
406427 current_time # set last time clicked to current time
407428 )
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
408442 user .add_xp (
409443 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 )))
425463 )
426- + user .combo_multiplier
427464 ) # add XP
428465 db .session .commit () # commit database changes
429466 return redirect (url_for ("index" )) # redirect to index page template
@@ -567,6 +604,12 @@ def init_db() -> None: # initialize database
567604 "ALTER TABLE user ADD COLUMN time_multiplier INT NOT NULL DEFAULT 1"
568605 )
569606 ) # 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
570613 if User .query .count () == 0 : # if there are no users
571614 new_user = User (username = "Player" ) # create new user
572615 db .session .add (new_user ) # add new user to the database
0 commit comments