What's the best Python idiom for this C construct?
while ((x = next()) != END) {
....
}
I don't have the ability to recode next().
update: and the answer from seems to be:
for x in iter(next, END):
....
#Mark Harrison's answer:
for x in iter(next_, END):
....
Here's an excerpt from Python's documentation:
iter(o[, sentinel])
Return an iterator object.
...(snip)... If the second argument, sentinel, is given, then o must be
a callable object. The iterator
created in this case will call o
with no arguments for each call to its
next() method; if the value returned
is equal to sentinel,
StopIteration will be raised,
otherwise the value will be returned.
It depends a bit what you want to do. To match your example as far as possible, I would make next a generator and iterate over it:
def next():
for num in range(10):
yield num
for x in next():
print x
Short answer: there's no way to do inline variable assignment in a while loop in Python. Meaning that I cannot say:
while x=next():
// do something here!
Since that's not possible, there are a number of "idiomatically correct" ways of doing this:
while 1:
x = next()
if x != END:
// Blah
else:
break
Obviously, this is kind of ugly. You can also use one of the "iterator" approaches listed above, but, again, that may not be ideal. Finally, you can use the "pita pocket" approach that I actually just found while googling:
class Pita( object ):
__slots__ = ('pocket',)
marker = object()
def __init__(self, v=marker):
if v is not self.marker:
self.pocket = v
def __call__(self, v=marker):
if v is not self.marker:
self.pocket = v
return self.pocket
Now you can do:
p = Pita()
while p( next() ) != END:
// do stuff with p.pocket!
Thanks for this question; learning about the __call__ idiom was really cool! :)
EDIT: I'd like to give credit where credit is due. The 'pita pocket' idiom was found here
Maybe it's not terribly idiomatic, but I'd be inclined to go with
x = next()
while x != END:
do_something_with_x
x = next()
... but that's because I find that sort of thing easy to read
What are you trying to do here?
If you're iterating over a list, you can use for e in L where e is the element and L is the list. If you're filtering a list, you can use list comprehensions (i.e. [ e for e in L if e % 2 == 0 ] to get all the even numbers in a list).
Can you provide more information about what you're trying to accomplish? It's not clear to me why you can't just say
for x in everything():
...
and have the everything function return everything, instead of writing a next function to just return one thing at a time. Generators can even do this quite efficiently.
If you need to do this more than once, the pythonic way would use an iterator
for x in iternext():
do_something_with_x
where iternext would be defined using something like
(explicit is better than implicit!):
def iternext():
x = next()
while x != END:
yield x
x = next()
Related
For example lets take the value 10.23E-4. What I did was break it up into several variables, whole=10, decimal=23, decimalLength=2, isNegative=1, exponent=4 (is there a better name for these?)
First I d = decimal; d*/exp10(decimalLength); d+=whole;. This gets me 10.23. Next I wrote e = exp10(exponent); if (isNegative) e = 1/e; result = d*e;. I suspect this part is wrong. My result is 0.0010229999999999998 while strtod is 0.001023. What's the proper way to handle the exponent? Is there a good+fast implementation of strtod I can compare my code to?
I am super new to sml. I am trying to write a simple code that takes an array of 5 positions with certain numbers and returns the length of the smallest subarray that contains all numbers. However I am getting many error messages that I cannot find in Google. Can anyone help me? The code is the following
fun Min x y = if x>y then return y else return x
local
val a = Array.array (3,0)
val cordela = Array.array(5,0)
val k=0
val front=0
val tail=0
val min=5
update(cordela,0,1)
update(cordela,1,3)
update(cordela,2,3)
update(cordela,3,2)
update(cordela,4,1)
in
fun loop front =
case k>3 of
if sub(a,sub(cordela,front)-1) = 0 then k=k+1 else()
update(a,sub(cordela,front)-1),sub(a,sub(cordela,front)-1)+1)
front = front +1
|
min= Min (front-tail) min
if sub(a,sub(cordela,front)-1) = 0 then k=k-1 else()
update(a,sub(cordela,front)-1),sub(a,sub(cordela,front)-1)-1)
tail=tail+1
if 5>front then loop front+1 else min
end
The error messages that I get are:
pl2.sml:16.13-16.15 Error: syntax error: replacing OF with LBRACKET
pl2.sml:18.36 Error: syntax error: inserting LPAREN
pl2.sml:20.4 Error: syntax error: replacing BAR with EQUALOP
pl2.sml:22.5 Error: syntax error: inserting LPAREN
pl2.sml:26.4 Error: syntax error: inserting LPAREN
pl2.sml:27.2 Error: syntax error found at END
Edit: I am trying to write this code in sml. It is written in c++
while(front < N){
if( k < K ){
if ( e[cordela[front]-1] == 0 ) k += 1;
e[cordela[front]-1] +=1;
front++ ;
}
else{
min = MIN(front - tail ,min);
if ( e[cordela[tail]-1] ==1 ) k -= 1;
e[cordela[tail]-1] -= 1;
tail++;
}
}
As John Coleman says, SML/NJ will not give very helpful error messages. You could try and install Moscow ML instead, since it gives better error messages. Unfortunately, there are some things wrong with this code at a syntactic level that makes it difficult for the compiler to give a meaningful error. Here are some hints to get the syntax right so that you can focus on the algorithm problems:
Don't use local, use let.
Match each ( with a ); you have too many )s.
Declare fun loop ... = ... inside let and in.
Once you've done that, a template for the function that solves your problem could look like:
fun smallest_subarray (needles : Array.array, haystack : Array.array) =
let
val ... = ...
fun loop ... = ...
in
if Array.length needles > Array.length haystack
then ...
else loop ...
end
What if there's no solution to the problem, what will the function return? ~1? NONE?
If you're trying to convert a C++ program to SML, try and include the function part in such a way that it's obvious what identifiers are arguments to the function, and try to name them logically; I have no idea what cordela, e and k are, or if N is a function of the size of the input array, or a constant.
Since an idiomatic solution in SML uses recursion (the function calling itself) rather than iteration (while), you are dealing with both a non-trivial algorithm problem and another paradigm. Try instead to solve a similar, but simpler problem where the algorithm is more trivial and apply the recursion paradigm.
For example, try and write a function that finds the position of an element in a sorted array using binary search:
fun find x arr =
let
fun loop ... = ...
in
loop ...
end
The loop function would take the search bounds (e.g. i and j) as argument and return either SOME i if x is found at position i, or NONE. You could extend this problem in the direction of your original problem by then trying to write a function that determines if an input array, needles, occurs in another input array, haystack, in the order given in needles. You could first assume that needles and haystack are sorted, and then assume that they're not.
I just realized that was a dumb question. Curious if anyone can still find a loophole though.
Source code:
married(trump,obama).
married(trump,goat).
married(pepee,pepper).
married(X,Y) :- married(Y,X),!. % not awesome because of infinite recursion
Goal: ex. married(trump, putin).
trace(
first base case fails.
second base case fails.
third base case fails.
married(trump,putin) = married(putin,trump),!.
what I want it doing is try married (putin,trump) again but all earlier base cases will fail again. We tried switching args before and failed. So don't recurse. Just return false.
I get a stack error because until married(putin,trump) or other way around before ! will never return true or false so cut will not be able triggered.
Easier and more sane way is to just rewrite the code to prevent recursion. I'm curious if there is a way to try switching args once and return fail if that fails. If u have a long list of facts, u can reduce that long list by half if u can try arg1,arg2 and vice versa. Potentially more exponentially if we get crazy permutation scenarios.
Any insights will be awesome thanks.
You are on the right track with "switching args once and return fail if that fails", even though that is worded very imperatively and does not cover all modes we expect from such a relation.
For this to work, you need to separate this into two predicates. It is easy to show that a single predicate with the given interface is not sufficient.
First, the auxiliary predicate:
married_(a, b).
married_(c, d).
etc.
Then, the main predicate, essentially as you suggest:
married(X, Y) :- married_(X, Y).
married(X, Y) :- married_(Y, X).
Adding impurities to your solution makes matters worse: Almost invariably, you will destroy the generality of your relations, raising the question why you are using a declarative language at all.
Example query:
?- married(X, Y).
X = a,
Y = b ;
X = c,
Y = d ;
X = b,
Y = a ;
X = d,
Y = c.
Strictly speaking, you can of course also do this with only a single predicate, but you need to carry around additional information if you do it this way.
For example:
married(_, a, b).
married(_, c, d).
married(first, X, Y) :- married(second, Y, X).
Example query:
?- married(_, X, Y).
X = a,
Y = b ;
X = c,
Y = d ;
X = b,
Y = a ;
X = d,
Y = c.
This closely follows the approach you describe: "We tried switching args before. So don't do it again."
I'am learning OCaml and currently i'am trying to undertand how iteration works in OCaml and how to create a matrix. I want an array 5 x 5 filled with 0. I know there is an issue with shared references so i created a new array at each iteration however iam having issues in other places, specifically at line 6. Let me know of other issues like indentation practices.
open Array;;
let n = ref 5 and i = ref 0 in
let m = Array.make !n 0 in
while !i < !n do
m.(!i) <- Array.make !n 0;;
i := !i + 1;;
done
m;;
You are using ;; too much. Contrary to popular belief, ;; is not part of ordinary OCaml syntax (in my opinion anyway). It's just a special way to tell the toplevel (the REPL) that you want it to evaluate what you've typed so far.
Leave the ;; after open Array. But change all but the last ;; to ; instead.
(Since you reference the Array module by name in your code, which IMHO is good style, you can also just leave out the open Array;; altogether.)
You want the last ;; because you do want the toplevel to evaluate what you've typed so far.
Your syntax error is caused by the fact that your overall code is like this
let ... in
let ... in
while ... do
...
done
m
The while is one expression (in OCaml everything is an expression) and m is another expression. If you want to have two expressions in a row you need ; between them. So you need ; after done.
You also have a type error. When you create m you're creating an array of ints (your given initial value is 0). So you can't make it into a matrix (an array of arrays) later in the code.
Also (not trying to overload you with criticisms :-) this code reads like imperative code. It's not particularly idiomatic OCaml code. In most people's code, using ref is pretty rare. One immediate improvement I see would just be to say let n = 5. You're not changing the value of n anywhere that I see (though maybe this is part of a larger chunk of code). Another improvement would be to use for instead of while.
Finally, you can do this entire operation in one function call:
let n = 5 in
let m = Array.init n (fun i -> Array.make n 0) in
m
Using explicit loops is actually also quite rare in OCaml (at least in my code).
Or you could try this:
let n = 5 in
let m = Array.make_matrix n n 0 in
m
I have a function that calculates f(n) in Haskell.
I have to write a loop so that it will start calculating values from f(0) to f(n), and will every time compare the value of f(i) with some fixed value.
I am an expert in OOP, hence I am finding it difficult to think in the functional way.
For example, I have to write something like
while (number < f(i))
i++
How would I write this in Haskell?
The standard approach here is
Create an infinite list containing all values of f(n).
Search this list until you find what you're after.
For example,
takeWhile (number <) $ map f [0..]
If you want to give up after you reach "n", you can easily add that as a separate step:
takeWhile (number <) $ take n $ map f [0..]
or, alternatively,
takeWhile (number <) $ map f [0 .. n]
You can do all sorts of other filtering, grouping and processing in this way. But it requires a mental shift. It's a bit like the difference between writing a for-loop to search a table, versus writing an SQL query. Think about Haskell as a bit like SQL, and you'll usually see how to structure your code.
You can generate the list of the is such that f i is larger than your number:
[ i | i<-[0..] , f i > number ]
Then, you can simply take the first one, if that's all you want:
head [ i | i<-[0..] , f i > number ]
Often, many idiomatic loops in imperative programming can be rephrased as list comprehensions, or expressed through map, filter, foldl, foldr. In the general case, when the loop is more complex, you can always exploit recursion instead.
Keep in mind that a "blind" translation from imperative to functional programming will often lead to non-idiomatic, hard-to-read code, as it would be the case when translating in the opposite direction. Still, I find it relieving that such translation is always possible.
If you are new to functional programming, I would advise against learning it by translating what you know about imperative programming. Rather, start from scratch following a good book (LYAH is a popular choice).
The first thing that's weird from a functional approach is that it's unclear what the result of your computation is. Do you care about the final result of f (i)? Perhaps you care about i itself. Without side effects everything neends to have a value.
Let's assume you want the final value of the function f (i) as soon as some comparison fails. You can simulate your own while loops using recursion and guards!
while :: Int -> Int -> (Int -> Int) -> Int
while start number f
| val >= number = val
| otherwise = while (start + 1) number f
where
val = f start
Instead of explicit recursion, you can use until e.g.
findGreaterThan :: (Int -> Int) -> Int -> Int -> (Int, Int)
findGreaterThan f init max = until (\(v, i) -> v >= max) (\(v, i) -> (f v, i + 1)) (init, 0)
this returns a pair containing the first value to fail the condition and the number of iterations of the given function.