Two Plus Two Publishing LLC Two Plus Two Publishing LLC
 

Go Back   Two Plus Two Poker Forums > Other Topics > Programming

Notices

Programming Discussions about computer programming

Reply
 
Thread Tools Display Modes
Old 06-10-2011, 01:41 PM   #61
Carpal \'Tunnel
 
jjshabado's Avatar
 
Join Date: Jul 2006
Posts: 11,092
Re: ** Python Support Thread **

Quote:
Originally Posted by Neil S View Post
Messing with a list while you iterate through it is generally a bad idea, and that's not python-specific.
Absolutely this. It'll definitely give you problems in Java (when I was a TA we had an assignment that constantly generated problems like this).

Edit:

And yes, you probably just want:

filter(lambda x: type(x) == int, list)

Edit again:

I'd consider this more readable. But that's pretty subjective. Especially since lots of stuff is considered readable by regular python users that isn't readable by people not use to it.
jjshabado is offline   Reply With Quote
Old 06-10-2011, 06:40 PM   #62
ɹǝʍoʇpunoɹ
 
RoundTower's Avatar
 
Join Date: Feb 2005
Location: soah made my profile
Posts: 13,926
Re: ** Python Support Thread **

Quote:
Originally Posted by jjshabado View Post
Absolutely this. It'll definitely give you problems in Java (when I was a TA we had an assignment that constantly generated problems like this).

Edit:

And yes, you probably just want:

filter(lambda x: type(x) == int, list)

Edit again:

I'd consider this more readable. But that's pretty subjective. Especially since lots of stuff is considered readable by regular python users that isn't readable by people not use to it.
I like maps and filters and lambdas but actually I don't think this is the "pythonic" way to do something. You are transforming a list into another list, therefore you should expect to be able to use a list comprehension here.

so something like:
Code:
list = [el for el in list if type(el) == int]
to do what you were suggesting. It doesn't have the same behaviour as tyler_cracker expected, though, because it doesn't convert floats or strings or other things that can be converted to integers.

So maybe something like
Code:
def convertable(x):
    try: return int(x)
    except ValueError: return None
list = [el for el in list if convertable(x) is not None]
By the way, I wouldn't use the name "list" either for the variable, it is legal Python code but you are shadowing the builtin list function and this might do something unexpected, particularly if the current function/method has more code in it.
RoundTower is offline   Reply With Quote
Old 06-11-2011, 02:54 PM   #63
Carpal \'Tunnel
 
tyler_cracker's Avatar
 
Join Date: Apr 2005
Location: Shallow End OTKP
Posts: 13,918
Re: ** Python Support Thread **

Quote:
Originally Posted by RoundTower View Post
I like maps and filters and lambdas but actually I don't think this is the "pythonic" way to do something. You are transforming a list into another list, therefore you should expect to be able to use a list comprehension here.

so something like:
Code:
list = [el for el in list if type(el) == int]
to do what you were suggesting. It doesn't have the same behaviour as tyler_cracker expected, though, because it doesn't convert floats or strings or other things that can be converted to integers.
i am far from an authority on how to make something look pythonic -- i come from perl and would rather use ruby and i will never find it intuitive to say str(object) instead of object.str() (though i understand why python does it that way). that said, i find the list comprehension form to be harder to understand than other representations. especially since, as you mentioned, i need to cast the things to ints, not simply throw away things that aren't ints.

Quote:
So maybe something like
Code:
def convertable(x):
    try: return int(x)
    except ValueError: return None
list = [el for el in list if convertable(x) is not None]
if we were on SO, this is the one i'd choose as The Answer.

"is not None" is another of those python things i feel i will never get used to.

Quote:
By the way, I wouldn't use the name "list" either for the variable, it is legal Python code but you are shadowing the builtin list function and this might do something unexpected, particularly if the current function/method has more code in it.
that was just example code, but good point for the audience.
tyler_cracker is offline   Reply With Quote
Old 06-11-2011, 06:49 PM   #64
ɹǝʍoʇpunoɹ
 
RoundTower's Avatar
 
Join Date: Feb 2005
Location: soah made my profile
Posts: 13,926
Re: ** Python Support Thread **

except I got it wrong, of course! I made a typo and a bad error.

because you need to be able to cast other things to integers, it needs to behave like

Code:
def convertable(x):
    try: return int(x)
    except ValueError: return None
list = [int(el) for el in list if convertable(el) is not None]
but that is unnecessarily ugly, it calls int() twice for every element. I'm not sure how to solve this in a nice way after all.

Last edited by RoundTower; 06-11-2011 at 07:06 PM.
RoundTower is offline   Reply With Quote
Old 06-11-2011, 09:35 PM   #65
veteran
 
Join Date: Jul 2004
Posts: 2,165
Re: ** Python Support Thread **

Has anyone here used the C API? I'm having trouble calling a C function from another C function.
Neuge is offline   Reply With Quote
Old 06-12-2011, 01:27 AM   #66
Carpal \'Tunnel
 
tyler_cracker's Avatar
 
Join Date: Apr 2005
Location: Shallow End OTKP
Posts: 13,918
Re: ** Python Support Thread **

maybe just post some code and see if anyone bites?
tyler_cracker is offline   Reply With Quote
Old 06-12-2011, 02:19 PM   #67
veteran
 
Join Date: Jul 2004
Posts: 2,165
Re: ** Python Support Thread **

Ok then. I've used the C API a lot before, and it's basically coding in C with a little gymnastics to pass values between C and python. I'm doing some project euler now to brush up on those skills now while I'm unemployed.

So this function takes int n and returns a list of all the factors of n (it's not complete yet, just the relevant code that's spitting out errors is here). isPrime returns True or False. I'm trying to check if n is prime before I try to factor it.

Code:
static PyObject *
euler_Factors(PyObject *self, PyObject *args){

    long n, i;
    int test;
    PyObject *res;

    if(!PyArg_Parse(args,"(l)",&n))
        return NULL;

    res = PyEval_CallFunction(euler_isPrime, "i", n);

    if(!(test = PyObject_IsTrue(res)))
      return NULL;

    printf("%d\n",test);

    return res;
}
Code:
static PyObject *
euler_isPrime(PyObject *self, PyObject *args){

    unsigned long long n, i, r;

    if(!PyArg_Parse(args,"(l)",&n))
        return NULL;

    r = (unsigned long long) (sqrt((double) (n))+1.0);

    if(n<2){
      Py_RETURN_FALSE;
    }
    else{
      for(i=3;i<r;i++){
        if(n%i == 0)
          Py_RETURN_FALSE;
      }
      Py_RETURN_TRUE;
    }

}
The problem is in

Code:
res = PyEval_CallFunction(euler_isPrime, "i", n);
I don't know what it's returning and can't figure out how to. It's obviously not returning Py_True or Py_False. When I compile the lib I get this warning message

Code:
euler.c:71: warning: passing argument 1 of ‘PyEval_CallFunction’ from incompatible pointer type
/usr/include/python2.6/ceval.h:21: note: expected ‘struct PyObject *’ but argument is of type ‘struct PyObject * (*)(struct PyObject *, struct PyObject *)’
It's obviously the wrong type, but I don't get how you're supposed to call a function without arguments.
Neuge is offline   Reply With Quote
Old 06-12-2011, 02:41 PM   #68
Carpal \'Tunnel
 
tyler_cracker's Avatar
 
Join Date: Apr 2005
Location: Shallow End OTKP
Posts: 13,918
Re: ** Python Support Thread **

no experience with c->python but i'll take a stab:

do you need to instantiate euler_isPrime before you use it? it's not clear to me where that value is coming from.

i also don't understand what you're doing with the long i and why you pass "i" to PyEval_CallFunction.

perhaps all of this is just my ignorance of the api. if so, at least we have quickly weeded out any advice i might give on this problem as useful.

edit: also did you look at ceval.h line 21 to see if that gave you any clue what was going on?
tyler_cracker is offline   Reply With Quote
Old 06-12-2011, 02:50 PM   #69
veteran
 
Join Date: Jul 2004
Posts: 2,165
Re: ** Python Support Thread **

Quote:
Originally Posted by tyler_cracker View Post
no experience with c->python but i'll take a stab:

do you need to instantiate euler_isPrime before you use it? it's not clear to me where that value is coming from.
This is what I suspect, but it would be a minor pain to create multiple libs just so you can call one function from another.

Quote:
i also don't understand what you're doing with the long i and why you pass "i" to PyEval_CallFunction.
That's prob a little confusing. long i is declared to use later in a loop. I'm not passing i to the function. "i" is there create a type Py_Int from n.

Quote:
edit: also did you look at ceval.h line 21 to see if that gave you any clue what was going on?
Not yet. I'm still a little too hungover to dive into that.
Neuge is offline   Reply With Quote
Old 06-12-2011, 05:55 PM   #70
ɹǝʍoʇpunoɹ
 
RoundTower's Avatar
 
Join Date: Feb 2005
Location: soah made my profile
Posts: 13,926
Re: ** Python Support Thread **

This reminds me that I shouldn't have put C on my resume.
RoundTower is offline   Reply With Quote
Old 06-13-2011, 09:15 AM   #71
Carpal \'Tunnel
 
jjshabado's Avatar
 
Join Date: Jul 2006
Posts: 11,092
Re: ** Python Support Thread **

Quote:
Originally Posted by RoundTower View Post
I like maps and filters and lambdas but actually I don't think this is the "pythonic" way to do something. You are transforming a list into another list, therefore you should expect to be able to use a list comprehension here.
I'm far from an expert on the "Pythonic" way , but what else is a function like filter useful for if not transforming a list?

That being said, I'd actually combine answers and define the function and put that in the filter method.

So:

Quote:
def convertible...
...
list = filter(convertible, list)
That seems by far the clearest answer of what you're doing. Also the easiest to test, verify correct.
jjshabado is offline   Reply With Quote
Old 06-13-2011, 11:30 AM   #72
old hand
 
sorrow's Avatar
 
Join Date: Apr 2008
Location: Perth, Western Australia
Posts: 1,500
Re: ** Python Support Thread **

Quote:
Originally Posted by RoundTower View Post
except I got it wrong, of course! I made a typo and a bad error.

because you need to be able to cast other things to integers, it needs to behave like

Code:
def convertable(x):
    try: return int(x)
    except ValueError: return None
list = [int(el) for el in list if convertable(el) is not None]
but that is unnecessarily ugly, it calls int() twice for every element. I'm not sure how to solve this in a nice way after all.
Code:
list = [int(x) for x in list if x.isdigit()]

Last edited by sorrow; 06-13-2011 at 11:32 AM. Reason: Forgot the cast
sorrow is offline   Reply With Quote
Old 06-13-2011, 11:34 AM   #73
Carpal \'Tunnel
 
jjshabado's Avatar
 
Join Date: Jul 2006
Posts: 11,092
Re: ** Python Support Thread **

That doesn't work since you can't call isdigit on an integer.
jjshabado is offline   Reply With Quote
Old 06-13-2011, 11:38 AM   #74
old hand
 
sorrow's Avatar
 
Join Date: Apr 2008
Location: Perth, Western Australia
Posts: 1,500
Re: ** Python Support Thread **

Quote:
Originally Posted by jjshabado View Post
That doesn't work since you can't call isdigit on an integer.
Oops - just as easy though:

Code:
[x for x in list if type(x) is int]
sorrow is offline   Reply With Quote
Old 06-13-2011, 11:44 AM   #75
Carpal \'Tunnel
 
jjshabado's Avatar
 
Join Date: Jul 2006
Posts: 11,092
Re: ** Python Support Thread **

Do people feel the list comprehension is better than using filter here? Seems weird to me.
jjshabado is offline   Reply With Quote

Reply
      

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off



All times are GMT -4. The time now is 10:09 AM.


Powered by vBulletin®
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO 3.6.0 ©2011, Crawlability, Inc.
Copyright © 2008-2010, Two Plus Two Interactive