Write a class called User that is used to calculate the amount that a user will progress through a ranking system similar to the one Codewars uses.  

##### Business Rules:

* A user starts at rank -8 and can progress all the way to 8.
* There is no 0 (zero) rank. The next rank after -1 is 1.
* Users will complete activities. These activities also have ranks.
* Each time the user completes a ranked activity the users rank progress is updated based off of the activity's rank
* The progress earned from the completed activity is relative to what the user's current rank is compared to the rank of the activity
* A user's rank progress starts off at zero, each time the progress reaches 100 the user's rank is upgraded to the next level
* Any remaining progress earned while in the previous rank will be applied towards the next rank's progress (we don't throw any progress away). The exception is if there is no other rank left to progress towards (Once you reach rank 8 there is no more progression). 
* A user cannot progress beyond rank 8. 
* The only acceptable range of rank values is -8,-7,-6,-5,-4,-3,-2,-1,1,2,3,4,5,6,7,8. Any other value should raise an error. 

The progress is scored like so:

* Completing an activity that is ranked the same as that of the user's will be worth 3 points
* Completing an activity that is ranked one ranking lower than the user's will be worth 1 point
* Any activities completed that are ranking 2 levels or more lower than the user's ranking will be ignored
* Completing an activity ranked higher than the current user's rank will accelerate the rank progression. The greater the difference between rankings the more the progression will be increased. The formula is `10 * d * d` where `d` equals the difference in ranking between the activity and the user.  

##### Logic Examples:
* If a user ranked -8 completes an activity ranked -7 they will receive 10 progress
* If a user ranked -8 completes an activity ranked -6 they will receive 40 progress
* If a user ranked -8 completes an activity ranked -5 they will receive 90 progress
* If a user ranked -8 completes an activity ranked -4 they will receive 160 progress, resulting in the user being upgraded to rank -7 and having earned 60 progress towards their next rank
* If a user ranked -1 completes an activity ranked 1 they will receive 10 progress (remember, zero rank is ignored)

##### Code Usage Examples:
```python
user = User()
user.rank # => -8
user.progress # => 0
user.inc_progress(-7)
user.progress # => 10
user.inc_progress(-5) # will add 90 progress
user.progress # => 0 # progress is now zero
user.rank # => -7 # rank was upgraded to -7
```

~~~if:java
**Note:** In **Java** some methods may throw an `IllegalArgumentException`.
~~~
~~~if:csharp
**Note:** In **C#** some methods may throw an `ArgumentException`.
~~~

**Note**: Codewars no longer uses this algorithm for its own ranking system. It uses a pure Math based solution that gives consistent results no matter what order a set of ranked activities are completed at.

Difficulty: interview

Starter code:

def __init__(self):
	

Solutions:
class User ():    
    def __init__ (self):
        self.RANKS = [-8, -7, -6, -5, -4, -3, -2, -1, 1, 2, 3, 4, 5, 6, 7, 8]
        self.rank = -8
        self.rank_index = 0
        self.progress = 0
        
    def inc_progress (self, rank):
        rank_index = self.RANKS.index(rank)
        
        if rank_index == self.rank_index:
            self.progress += 3
        elif rank_index == self.rank_index - 1:
            self.progress += 1
        elif rank_index > self.rank_index:
            difference = rank_index - self.rank_index
            self.progress += 10 * difference * difference
            
        while self.progress >= 100:
            self.rank_index += 1
            self.rank = self.RANKS[self.rank_index]
            self.progress -= 100    
        
        if self.rank == 8:
            self.progress = 0
            return

class User(object):
  def __init__(self):
    self.ranks, self.cur_rank, self.progress = [-8, -7, -6, -5, -4, -3, -2, -1, 1, 2, 3, 4, 5, 6, 7, 8], 0, 0
  def get_rank(self):
    return self.ranks[self.cur_rank]
  def set_rank(self, arg):
    '''Nope'''
  rank = property(get_rank, set_rank)
  def inc_progress(self, k_rank):
    k_rank = self.ranks.index(k_rank)
    if self.rank == 8: return
    if k_rank == self.cur_rank: self.progress += 3
    elif k_rank == self.cur_rank - 1: self.progress += 1
    elif k_rank > self.cur_rank:
      diff = k_rank - self.cur_rank
      self.progress += 10 * diff * diff
    while self.progress >= 100:
      self.cur_rank += 1
      self.progress -= 100
      if self.rank == 8:
        self.progress = 0
        return

class User:

    def __init__(self):
        self.rank = -8
        self.progress = 0

    def inc_progress(self, act):
        assert act in range(-8, 0) + range(1, 9)
        diff = act - (act > 0) - self.rank + (self.rank > 0)
        self.progress += (0, 1, 3, diff * diff * 10)[(diff > 0) + (diff >= 0) + (diff >= -1)]
        while self.progress >= 100:
            self.rank += 1 + (self.rank == -1)
            self.progress -= 100
        if self.rank >= 8:
            self.rank, self.progress = 8, 0

class User(object):
    
    MAX_RANK, MAX_PROGRESS, DELTA_RANKS = 8, 100, set(range(-8,9))-{0}
    
    def __init__(self):
        self.rank, self.progress = -8, 0
    
    def inc_progress(self, rank):
        if not rank in self.DELTA_RANKS:
            raise ValueError("Invalid value for activity rank")
        dRank = rank - self.rank + (rank * self.rank < 0) * (-1)**(rank > self.rank)
        self.updateProgress([0, 1, 3, 10 * dRank**2][ (dRank > -2) + (dRank >= 0) + (dRank > 0)] )
        
    def updateProgress(self,n):
        nLevel, self.progress = divmod(self.progress + n, self.MAX_PROGRESS)
        self.rank = min(self.MAX_RANK, self.rank + nLevel + (self.rank+nLevel not in self.DELTA_RANKS))
        if self.rank == self.MAX_RANK: self.progress = 0

class User:
    Ranks = [-8,-7,-6,-5,-4,-3,-2,-1,1,2,3,4,5,6,7,8]
    
    def __init__(self):
        self.__rank = -8
        self.__progress = 0
    
    @property
    def rank(self):
        return self.__rank
    
    @property
    def progress(self):
        return self.__progress
    
    def inc_progress(self, kata_rank):
        self.__validate_rank(kata_rank)
        progress_made = self.__calc_progress(kata_rank) 
        new_progress = self.progress + progress_made
        extra_rank, progress_left = self.__calc_rank(new_progress)
        self.__update_rank(extra_rank)
        self.__update_progress(progress_left)
        
    def __validate_rank(self, in_rank):
        if (in_rank not in self.Ranks):
            raise ValueError("Rank must be in range [-8,-1]U[1,8]")
        
    def __calc_progress(self, kata_rank):
        diff = self.Ranks.index(kata_rank) - self.Ranks.index(self.rank)
        if (kata_rank > self.rank):
            return 10 * diff ** 2
        elif (kata_rank == self.rank):
            return 3
        elif (diff == - 1):
            return 1
        else:
            return 0

    def __calc_rank(self, new_progress):
        extra_rank = 0
        progress_left = new_progress
        if (new_progress > 99 and self.rank < 8):
            extra_rank = new_progress // 100
            progress_left = new_progress % 100
        return extra_rank, progress_left
    
    def __update_progress(self, new_progress):
        self.__progress = new_progress
        if (self.rank == 8 and self.progress>0):
            self.__progress = 0
    
    def __update_rank(self, extra_rank):
        new_rank = self.rank + extra_rank
        if (self.rank < 0 and new_rank >= 0):
            new_rank = new_rank + 1
        if (new_rank > 8):
            self.__rank = 8
        else:
            self.__rank = new_rank            

class User:
    ranks = range(-8,0) + range(1,9)

    def __init__(self):
        self.rank = -8
        self.progress = 0
        
    def inc_progress(self, rank):
        if rank not in User.ranks :
            raise ValueError('Invalid rank')
        d = User.ranks.index(rank) - User.ranks.index(self.rank)
        p = 0 if d  < -1 else (
            1 if d == -1 else (
            3 if d ==  0 else 10 * d * d ))
        r = int( (self.progress + p) / 100 )
        r = User.ranks.index(self.rank) + r
        self.rank = User.ranks[r if r < len(User.ranks) else -1]
        self.progress = (self.progress + p) % (100 if self.rank < User.ranks[-1] else 1)

class User():
    '''Creates a User class for a codewars style website'''

    def __init__(self):
        self.ranks = [-8, -7, -6, -5, -4, -3, -2, -1, 1, 2, 3, 4, 5, 6, 7, 8]    #15
        self.progress = 0
        self.level = 0
        self.rank = self.ranks[self.level]

    def inc_progress(self, rank):

        if rank not in self.ranks:
            raise Exception('Invalid rank')
        
        activityrank = self.ranks.index(rank)
        rank = self.level
        difference = activityrank - rank

        if self.level < 15:

            if difference > 0:                                              
                points = 10 * difference * difference
                self.progress += points

            elif difference == 0: self.progress += 3

            elif difference == -1: self.progress += 1 
            
            if self.progress == 100:
                self.level += 1 
                self.rank = self.ranks[self.level]
                self.progress = 0

            while self.progress >= 100:
                self.level += 1
                leftover = self.progress - 100
                self.rank = self.ranks[self.level]

                if self.level < 15:
                    self.progress = leftover

                elif self.level >= 15:
                    self.progress = 0

class User():
    def __init__(self):
        self.rank = -8
        self.ranks = [-8,-7,-6,-5,-4,-3,-2,-1,1,2,3,4,5,6,7,8]
        self.relative_rank = self.ranks.index(self.rank)
        self.progress = 0
        
    
    def rank(self):
        print("rank")
        print((self.rank))
        print((self.progress))
        return self.rank
    def progress(self):
        print("progrees")
        print((self.rank))
        print((self.progress))
        return self.progress
    
    
    def inc_progress(self,kata):
        print("inc:")
        print(("rank",self.rank))
        print(("rank relative",self.relative_rank))
        print(("progress",self.progress))
        print(("kata",kata))
        
        if kata > 8 or kata < -8 or kata == 0:
            raise "Bruh"
        
        relative_rank = self.ranks.index(kata) ### Relvative rank of the kata. Starts from 0, goes to 15.
        print(("kata relative",relative_rank))
        
        print()
        if self.rank == kata:
            self.progress += 3
        elif self.relative_rank - 1 == relative_rank and self.relative_rank != 0:
            self.progress += 1
        elif self.relative_rank < relative_rank:
            self.progress += 10 * ((relative_rank - self.relative_rank) ** 2)
        
        if self.progress >= 100:
            self.relative_rank += self.progress // 100
            if self.relative_rank > 15:
                self.relative_rank = 15
    
            self.progress %= 100
        
            self.rank = self.ranks[self.relative_rank]
        if self.rank > 7:
            self.progress = 0