~~~if-not:java
You have to code a function **getAllPrimeFactors** wich take an integer as parameter and return an array containing its prime decomposition by ascending factors, if a factors appears multiple time in the decomposition it should appear as many time in the array. 

exemple: `getAllPrimeFactors(100)` returns `[2,2,5,5]` in this order. 

This decomposition may not be the most practical. 

You should also write **getUniquePrimeFactorsWithCount**, a function which will return an array containing two arrays: one with prime numbers appearing in the decomposition and the other containing their respective power. 

exemple: `getUniquePrimeFactorsWithCount(100)` returns `[[2,5],[2,2]]`

You should also write **getUniquePrimeFactorsWithProducts** an array containing the prime factors to their respective powers. 

exemple: `getUniquePrimeFactorsWithProducts(100)` returns `[4,25]`
~~~
~~~if:java
You have to code a function **getAllPrimeFactors** wich take an integer as parameter and return an array containing its prime decomposition by ascending factors, if a factors appears multiple time in the decomposition it should appear as many time in the array. 

exemple: `getAllPrimeFactors(100)` returns `[2,2,5,5]` in this order. 

This decomposition may not be the most practical. 

You should also write **getUniquePrimeFactorsWithCount**, a function which will return an array containing two arrays: one with prime numbers appearing in the decomposition and the other containing their respective power. 

exemple: `getUniquePrimeFactorsWithCount(100)` returns `[[2,5],[2,2]]`

You should also write **getPrimeFactorPotencies** an array containing the prime factors to their respective powers. 

exemple: `getPrimeFactorPotencies(100)` returns `[4,25]`
~~~

Errors, if:

* `n` is not a number
* `n` not an integer 
* `n` is negative or 0 

The three functions should respectively return `[]`,  `[[],[]]` and `[]`. 

Edge cases: 

* if `n=0`, the function should respectively return `[]`, `[[],[]]` and  `[]`.
* if `n=1`, the function should respectively return `[1]`, `[[1],[1]]`, `[1]`.
* if `n=2`, the function should respectively return `[2]`, `[[2],[1]]`, `[2]`.

The result for `n=2` is normal. The result for `n=1` is arbitrary and has been chosen to return a usefull result. The result for `n=0` is also arbitrary 
but can not be chosen to be both usefull and intuitive. (`[[0],[0]]` would be meaningfull but wont work for general use of decomposition, `[[0],[1]]` would work but is not intuitive.)

Difficulty: introductory

Starter code:

def getAllPrimeFactors(n):
	

Solutions:
def getAllPrimeFactors(n):
    if n == 0: return []
    elif n == 1: return [1]
    elif type(n) != int: return errora
    elif n < 0: return errora
    allfacts = []
    current = 2
    n_copy = n
    while current <= n:
        if n_copy % current == 0:
            allfacts.append(current)
            n_copy /= current
        else:
            current += 1
    return allfacts
    
    
def getUniquePrimeFactorsWithCount(n):
    if type(n) != int: return errorb
    elif n < 0: return errorb
    primes = []
    power = []
    listA = getAllPrimeFactors(n)
    for i in range(len(listA)):
        if listA[i] not in primes:
            primes.append(listA[i])
            power.append(1)
        else:
            power[-1] += 1
    return [primes, power]

def getUniquePrimeFactorsWithProducts(n):
    if type(n) != int: return errorc
    elif n < 0: return errorc
    listlist = getUniquePrimeFactorsWithCount(n)
    listc = []
    for i in range(len(listlist[0])):
        listc.append(listlist[0][i] ** listlist[1][i])
    return listc

errora = []
errorb = [[], []]
errorc = []

from collections import Counter
def getAllPrimeFactors(n):
  if type(n)!=int:return []
  li, j = [], 2
  while j*j <= n:
      if n % j : j += 1 ; continue
      li.append(j) ; n //= j
  return li + [[n],[]][n<1]

def getUniquePrimeFactorsWithCount(n):
  r = Counter(getAllPrimeFactors(n))
  return [list(r.keys()),list(r.values())]

getUniquePrimeFactorsWithProducts=lambda n:[i**j for i,j in zip(*getUniquePrimeFactorsWithCount(n))]

from collections import defaultdict
from functools import lru_cache
from itertools import chain

@lru_cache(maxsize=None)
def factors(n):
    if n == 1: return [(1, 1)]
    res, wheel = defaultdict(int), [1, 2, 2, 4, 2, 4, 2, 4, 6, 2, 6]
    x, y = 2, 0
    while x*x <= n:
        if not n%x:
            res[x] += 1
            n //= x
        else:
            x += wheel[y]
            y = 3 if y == 10 else y+1
    res[n] += 1
    return res.items()

def getAllPrimeFactors(n):
    return list(chain.from_iterable([k]*v for k,v in factors(n))) if isinstance(n, int) and n > 0 else []

def getUniquePrimeFactorsWithCount(n):
    return list(map(list, zip(*factors(n)))) if isinstance(n, int) and n > 0 else [[], []]

def getUniquePrimeFactorsWithProducts(n):
    return [k**v for k,v in factors(n)] if isinstance(n, int) and n > 0 else []


        
def getAllPrimeFactors(n):
    result = []
    if isinstance(n, int) and n > 0 :
        if n == 1:
            result = [1]
        number = 2
        while n > 1:
            print(n)
            if not n % number :
                result.append(number)
                n /= number
                number = 2
            else:
                number += 1
    return result
                
            
  #your code here

def getUniquePrimeFactorsWithCount(n):
    pf = getAllPrimeFactors(n)
    r1 = []
    r2 = []
    if pf:
        r1 = list(set(pf))
        r2 = [pf.count(x) for x in r1 ]
    return [r1, r2]
                

def getUniquePrimeFactorsWithProducts(n):
    return [x ** y for (x,y) in zip(*getUniquePrimeFactorsWithCount(n))]

import math
import collections


def getAllPrimeFactors(n):
    if isinstance(n, int) and n > -1:
        if n != 1:
            listy, m, x = [], n, True
            while x:
                for i in range(2, int(math.sqrt(n)) + 1):
                    if n % i == 0:
                        n = n // i
                        listy.append(i)
                        break
                else:
                    x = False
            if m > 1:
                listy.append(n)
            return listy
        else:
            return [1]
    else:
        return []
def getUniquePrimeFactorsWithCount(n):
    if isinstance(n, int) and n > -1:
        if n != 1:
            listy, m, x = [], n, True
            while x:
                for i in range(2, int(math.sqrt(n)) + 1):
                    if n % i == 0:
                        n = n // i
                        listy.append(i)
                        break
                else:
                    x = False
            if m > 1:
                listy.append(n)
        else:
            listy = [1]
    else:
        listy = []
    fancy_dict = collections.Counter()
    resulty_list = [[],[]]
    for number in listy:
        fancy_dict[number] += 1
    for key, value in list(fancy_dict.items()):
        resulty_list[0].append(key)
        resulty_list[1].append(value)
    return resulty_list

def getUniquePrimeFactorsWithProducts(n):
    if isinstance(n, int) and n > -1:
        if n != 1:
            listy, m, x = [], n, True
            while x:
                for i in range(2, int(math.sqrt(n)) + 1):
                    if n % i == 0:
                        n = n // i
                        listy.append(i)
                        break
                else:
                    x = False
            if m > 1:
                listy.append(n)
        else:
            listy = [1]
    else:
        listy = []
    fancy_dict = collections.Counter()
    resulty_list = [[],[]]
    for number in listy:
        fancy_dict[number] += 1
    for key, value in list(fancy_dict.items()):
        resulty_list[0].append(key)
        resulty_list[1].append(value)
    return [resulty_list[0][i]**resulty_list[1][i] for i in range(len(resulty_list[0]))]


# RWH primes
LIMIT = 10**6
sieve = [True] * (LIMIT//2)
for i in range(3, int(LIMIT**0.5)+1, 2):
    if sieve[i//2]: sieve[i*i//2::i] = [False] * ((LIMIT-i*i-1)//2//i+1)
PRIMES = [2] + [2*i+1 for i in range(1, LIMIT//2) if sieve[i]]


from collections import Counter

def getAllPrimeFactors(n):
    # errors and zero
    if not type(n) == int or n < 1:
        return []
    
    # edge cases
    if n in (1, 2):
        return [n]
    
    # factorisation
    factors = []
    
    for p in PRIMES:
        if p*p > n:
            break
        while n % p == 0:
            n //= p
            factors.append(p)
    
    return factors + [n] * (n > 1)


def getUniquePrimeFactorsWithCount(n):
    factors = Counter(getAllPrimeFactors(n))
    return [ list(factors.keys()), list(factors.values()) ]


def getUniquePrimeFactorsWithProducts(n):
    factors = Counter(getAllPrimeFactors(n))
    return [ p**e for p, e in factors.items() ]

from collections import Counter

def getAllPrimeFactors(n):
    if n==1: return [1]
    lst, p, n = [], 2, 1 if not isinstance(n,int) or n<0 else n
    while n>1:
        while not n%p:
            lst.append(p)
            n //= p
        p += 1 + (p!=2)
    return lst

def getUniquePrimeFactorsWithCount(n):
    return list(map(list, zip(*Counter(getAllPrimeFactors(n)).items()))) or [[],[]]

def getUniquePrimeFactorsWithProducts(n):
    return [k**v for k,v in Counter(getAllPrimeFactors(n)).items()]

def getAllPrimeFactors(n):
    if not type(n) is int:
        n = 0
    elif n < 0:
        n = 0
    results = []
    number = 2
    while number < n:
        if not n % number:
            n /= number
            results.append(number)
            number = 2
        else:
            number += 1
    if n: results.append(int(n))
    return results

def getUniquePrimeFactorsWithCount(n):
    results = getAllPrimeFactors(n)
    counted = [[],[]]
    if not results == []:
        for i in range(results[-1]+1):
            if i in results: 
                counted[0].append(i)
                counted[1].append(results.count(i))            
    return counted

def getUniquePrimeFactorsWithProducts(n):
    counted = getUniquePrimeFactorsWithCount(n)
    products = []
    if not counted == [[],[]]:
        for i in range(len(counted[0])):
            products.append(counted[0][i]**counted[1][i])
    return products

def getAllPrimeFactors(n):
  if type(n) is not int or n < 1:
      return []
  elif n < 3:
      return [n]
  factors = []
  while n > 1:
      for i in range(2, n+1):
          if is_prime(i) and not n % i:
              factors.append(i)
              n = int(n/i)
              break
  return factors

def getUniquePrimeFactorsWithCount(n):
  f = getAllPrimeFactors(n)
  factors = list(set(f))
  powers = [f.count(factor) for factor in factors]
  return [factors, powers]

def getUniquePrimeFactorsWithProducts(n):
  cf = getUniquePrimeFactorsWithCount(n)
  return [factor**count for factor, count in zip(cf[0], cf[1])]
  
def is_prime(n):
    for i in range(2, n):
        if not n % i:
            return False
    return True