misunderstanding about Range in python 2.7 - python-2.7

I've been doing some exercises, and having one question for you guys.
following to the picture I added.
for number =2 the range we get in the second line is from 2 until 2.
so, why dont i get some error message? How does it work?
How does the program know to skip it and return True?
Code:
def main(number):
for i in range(2,int(number**0.5)+1):
if number % i == 0:
return False
return True
print main(2)
Thanks!!

Some people think that Python attaches some special syntax between for and range, but range is an object that supports iteration.
This means that it has an __iter__ function that returns an iterator, and this supports the iterator protocol. This is a protocol that allows us to enumerate items out of that object. Like we can also enumerate over a list, tuple, set, etc.
for on the other hand simply uses this protocol such that for each iteration, it aims to fetch the next element out of the iterator. In case there is a next element, it assigns that element to the variable(s) on the left side. In case the iterator is exhausted (has no elements anymore), it stops.
In case you construct a range(start,stop) object where stop <= start. That range object is considered to be empty: it simply does not enumerate any items. for does not know what it is enumerating, but since the iterator over the range(..) element simply says that there are no elements anymore for stops.
You might indeed argue that it would be better if range(..) raises an error in case the stop is less than or equal to start. But usually it is wanted behavior that no error is risen, and the loop simply does not execute.
You can compare for i in range(0,n) to a construct in the Java/C++ language family:
for(int i = 0; i < n; i++) {
//...
}
In this case if n is less than or equal to zero, the loop will not be executed either. The range(..) object somewhat a generator for such type of loops.
A extra note is that range actually is more sophisticated than described here in this answer, since you can also add a step, and you can countdown. But this has no impact on the semantics of this answer.
You can make the code more elegant, by using a generator in an all statement. Like:
def main(number):
return all(number % i for i in range(2,int(number**0.5)+1))
Furthermore we can boost performance a bit, by only checking odd divisors (and 2):
def main(number):
sq = int(number ** 0.5) + 1
return (number & 1) and all(number % i for i in range(3, n, 2))

Related

dart performance for iterables using where

i'm trying to get better performance from a pattern check in a really wide list of strings.
i need the 5 first occurences that would match a given pattern.
i was wondering if
list.where(pattern in string).take(5)
was lazily computed and stops after 5 occurences found or
does it compute all the where and then takes the 5 first ? ( in that case, is there a whereXfirstOccurences method where X is a number ? )
thank you,
Edit:
i did some investigation
myList.where((element) {bool isSuggestion = the conditions ;
if (isSuggestion) index++;
return isSuggestion;
})
.take(x)
.toList();
print(index);
the index is always at most equal to x so i guess it's lazy evaluation as mentionned below, Thank you :)
Iterables are lazy.
If you do list.where(computation).take(5), it:
Doesn't do anything at all, until you start iterating.
It doesn't do anything except when you call moveNext on the iterator.
And it stops doing anything once moveNext has returned false, which it does after five elements here, because of the take(5).
If you just use for (var v in list.where(...).take(5)) ... you won't see those steps, but they are still there. The loop stops after finding five values, and no further elements are looked at than the ones needed to find the first five satisfying the where condition.
That might still be a lot of strings looked at, if the condition is very picky. If there are only four matching strings in the input, you will go through all of the input when looking for the first five matches.
Optimizing the pattern itself can definitely be valuable as well.

Duplicate values in Julia with Function

I need writing a function which takes as input
a = [12,39,48,36]
and produces as output
b=[4,4,4,13,13,13,16,16,16,12,12,12]
where the idea is to repeat one element three times or two times (this should be variable) and divided by 2 or 3.
I tried doing this:
c=[12,39,48,36]
a=size(c)
for i in a
repeat(c[i]/3,3)
end
You need to vectorize the division operator with a dot ..
Additionally I understand that you want results to be Int - you can vectorizing casting to Int too:
repeat(Int.(a./3), inner=3)
Przemyslaw's answer, repeat(Int.(a./3), inner=3), is excellent and is how you should write your code for conciseness and clarity. Let me in this answer analyze your attempted solution and offer a revised solution which preserves your intent. (I find that this is often useful for educational purposes).
Your code is:
c = [12,39,48,36]
a = size(c)
for i in a
repeat(c[i]/3, 3)
end
The immediate fix is:
c = [12,39,48,36]
output = Int[]
for x in c
append!(output, fill(x/3, 3))
end
Here are the changes I made:
You need an array to actually store the output. The repeat function, which you use in your loop, would produce a result, but this result would be thrown away! Instead, we define an initially empty output = Int[] and then append! each repeated block.
Your for loop specification is iterating over a size tuple (4,), which generates just a single number 4. (Probably, you misunderstand the purpose of the size function: it is primarily useful for multidimensional arrays.) To fix it, you could do a = 1:length(c) instead of a = size(c). But you don't actually need the index i, you only require the elements x of c directly, so we can simplify the loop to just for x in c.
Finally, repeat is designed for arrays. It does not work for a single scalar (this is probably the error you are seeing); you can use the more appropriate fill(scalar, n) to get [scalar, ..., scalar].

How to detect list changes without comparing the complete list

I have a function which will fail if there has being any change on the term/list it is using since the generation of this term/list. I would like to avoid to check that each parameter still the same. So I had thought about each time I generate the term/list to perform a CRC or something similar. Before making use of it I would generate again the CRC so I can be 99,9999% sure the term/list still the same.
Going to a specfic answer, I am programming in Erlang, I am thinking on using a function of the following type:
-spec(list_crc32(List :: [term()]) -> CRC32 :: integer()).
I use term, because it is a list of terms, (erlang has already a default fast CRC libraries but for binary values). I have consider to use "erlang:crc32(term_to_binary(Term))", but not sure if there could be a better approach.
What do you think?
Regards, Borja.
Without more context it is a little bit difficult to understand why you would have this problem, particularly since Erlang terms are immutable -- once assigned no other operation can change the value of a variable, not even in the same function.
So if your question is "How do I quickly assert that true = A == A?" then consider this code:
A = generate_list()
% other things in this function happen
A = A.
The above snippet will always assert that A is still A, because it is not possible to change A like you might do in, say, Python.
If your question is "How do I assert that the value of a new list generated exactly the same value as a different known list?" then using either matching or an actual assertion is the fastest way:
start() ->
A = generate_list(),
assert_loop(A).
assert_loop(A) ->
ok = do_stuff(),
A = generate_list(),
assert_loop(A).
The assert_loop/1 function above is forcing an assertion that the output of generate_list/0 is still exactly A. There is no telling what other things in the system might be happening which may have affected the result of that function, but the line A = generate_list() will crash if the list returned is not exactly the same value as A.
In fact, there is no way to change the A in this example, no matter how many times we execute assert_loop/1 above.
Now consider a different style:
compare_loop(A) ->
ok = do_stuff(),
case A =:= generate_list() of
true -> compare_loop(A);
false -> terminate_gracefully()
end.
Here we have given ourselves the option to do something other than crash, but the effect is ultimately the same, as the =:= is not merely a test of equality, it is a match test meaning that the two do not evaluate to the same values, but that they actually match.
Consider:
1> 1 == 1.0.
true
2> 1 =:= 1.0.
false
The fastest way to compare two terms will depend partly on the sizes of the lists involved but especially on whether or not you expect the assertion to pass or fail more often.
If the check is expected to fail more often then the fastest check is to use an assertion with =, an equivalence test with == or a match test with =:= instead of using erlang:phash2/1. Why? Because these tests can return false as soon as a non-matching element is encountered -- and if this non-match occurs near the beginning of the list then a full traverse of both lists is avoided entirely.
If the check is expected to pass more often then something like erlang:phash2/1 will be faster, but only if the lists are long, because only one list will be fully traversed each iteration (the hash of the original list is already stored). It is possible, though, on a short list that a simple comparison will still be faster than computing a hash, storing it, computing another hash, and then comparing the hashes (obviously). So, as always, benchmark.
A phash2 version could look like:
start() ->
A = generate_list(),
Hash = erlang:phash2(A),
assert_loop(Hash).
assert_loop(Hash) ->
ok = do_stuff(),
Hash = erlang:phash2(generate_list()),
loop(Hash).
Again, this is an assertive loop that will crash instead of exit cleanly, so it would need to be adapted to your needs.
The basic mystery still remains, though: in a language with immutable variables why is it that you don't know whether something will have changed? This is almost certainly a symptom of an underlying architectural problem elsewhere in the program -- either that or simply a misunderstanding of immutability in Erlang.

break for loop in Python [duplicate]

This question already has answers here:
How to change index of a for loop?
(5 answers)
Closed 4 months ago.
is it possible to break a for loop in Python, without break command?
I'm asking this question in order to compare it with C++ for loop, in which actually checks a condition each time.
i.e. it's possible to break a for loop in C++ like below:
for(int i=0; i<100; i++)
i = 1000; // equal to break;
is it possible to do the same in Python?
for i in range(0,100):
i = 10000 // not working
Python's for is really a "for each" and is used with iterables, not loop conditions.
Instead, use a while statement, which checks the loop condition on each pass:
i = 0
while i < 1000:
i = 1000
Or use an if statement paired with a break statement to exit the loop:
for i in range(1000):
if i == 10:
break
Use a while loop for that purpose:
i = 0
while i < 100:
i = 1000
No, for doesn't work like that in Python. for iterates over a list (in this case) or other container or iterable. for i in range(0, 100) doesn't mean "increment i until i is greater than or equal to 100", it means "set i to successive items from a list of these 100 items until the list is exhausted."
If i is 50, then the next item of the list is still 51, regardless of what you may set i to.
break is better anyway.
This won't work (as you've noticed). The reason is that, in principle, you are iterating the elements of a list of ascending numbers (whether that is really true depends on if you're using python 2 or 3). You can use the 'break' keyword to break out of a loop at any time, although using it in excess might make it hard to follow your code.
You might have to settle for the break statement:
http://docs.python.org/tutorial/controlflow.html
for i in range(0,100):
print i
if i == 10:
break

simple yes/no haskell list question

So I'm reading http://learnyouahaskell.com/starting-out as it explains lists, and using ghci on Vista 64. It says that [2,4..20] steps by 2 from 4 to 20. This works. It says [20,19..1] goes from 20 to 1, but doesn't explain. I take it that the first number is NOT the step, the step is the difference between the 1st and 2nd number. This is confirmed by [4,4..20] which hangs (no error message, must kill console). This is unlike operators like !! and take which check the index's range and give an error message.
My question is: is this a bug on Vista port or is that the way it's supposed to be?
[x,y..z] does indeed step from x to z by step y-x. When y-x is 0 this leads to an infinite list. This is intended behavior.
Note that if you use the list in an expression like take 20 [2,2..20], ghci won't try to print the whole list (which is impossible with infinite lists of course) and it won't "hang".
Quoting this book:
[n,p..m] is the list of numbers from n to m in steps of p-n.
Your list [4,4..20] "hangs", because you have a step of 4-4=0, so it's an infinite list containing only the number 4 ([4, 4, 4, 4...]).
Haskell allows infinite lists and as the Haskell is the "lazy evaluation language", meaning it will only compute what is necessary to give you the result, so the infinite structures are allowed in Haskell.
In Haskell you could compute something like "head[1..]". This is because Haskell only calculates what is required for the result. So in the example above it would generate only the first element of the infinite list (number 1) and head would return you this element (number 1).
So, in that case program will terminate! However, if you calculate [1..] (infinite list) program won't terminate. Same applies to your example, you created an infinite list and there is no way of terminating it.
That syntax basically is derived from listing the whole list. [1,3,5,7,9,11,13,15,17,19] for example can be shortened by simply omitting the obvious parts. So you could say, if I specify the first two elements, it is clear how it would continue. So the above list equals to [1,3..19].
It's worth noting that the .. syntax in lists desugars to the enumFrom functions given by the Enum typeclass:
http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#t:Enum