What we have here is a deterministic approach (brute force) that doesn't seek any efficiency, but goes through the entire range before letting a value pass. For large values of
x this will get progressively slower.
We can make it more efficient in a number of ways, mostly in setting the range. The first approach would be to consider that any value larger than half of a number is not divisible into that number, so we can divide the range in half, right off the top. It will still be deterministic, though, just less iterations.
Getting more into factoring theory, we also know that the square root of a number is the largest factor we need to seek, since the opposite factor can be determined through normal division.
27 % 3 == 0
27 / 3 == 9
In this sense, we reduce the field to only those numbers between 2 and the square root of x. Again, way fewer iterations.
Is 25 prime?
25 % 2
25 % 3
25 % 4
25 % 5
Only four iterations to show that it is not. Notice that 5 is the square root of 25.
The final improvement on this approach would be to iterate only a list of odd numbers since no even numbers besides 2 are prime. Once we factor out two, we can step in two;s from 3 onward. It requires a reworking of the above example, but not by too much. Give it a try when you are up for the practice.
I left out one profound improvement... A list of primes only. This is indeed the fewest number of iterations, but we need a list of primes to begin with, or have our function generate an appropriate list in each case. Again, more study and practice when you are looking for something to explore.