Prime factorization program
while found_last_factor == False:



Style is subjective, but I know I'm not the only develop who considers comparisons to Boolean literals to be bad style. while not found_last_factor: is an alternative which I consider preferable.



There are various inefficiencies in this code:


    while found_last_factor == False:
        for f in range(2, int(n/2+1)):
            if n % f == 0 and is_prime(f):
                n /= f
                factors.append(f)
                if is_prime(n): 
                    factors.append(n)
                    found_last_factor = True
                    break
    return sorted(factors)




If it were modified to handle repeated prime factors in an inner loop rather than in the outmost loop then


The test is_prime(f) would be unnecessary, because n % f == 0 would already imply the primality of f.
Primes would be discovered in order, removing the need to call sorted.
A lot of unnecessary iterations of f would be saved. You rebutted AJNeufeld's observation on this subject, so consider an alternative perspective: add a line print(f) at the top of the for f loop, and then call prime_factors(1024).

The call to is_prime(n) tests primality by trial division, and is called from a loop which is factoring n by trial division. That's duplication of both code and run time.




/= does floating point division. Use //= for integer division. Similarly int(n/2+1) could be n//2 + 1.