Two Plus Two Poker Forums

Two Plus Two Poker Forums (https://forumserver.twoplustwo.com/)
-   Computer and Technical Help (https://forumserver.twoplustwo.com/48/computer-technical-help/)
-   -   ** Python Support Thread ** (https://forumserver.twoplustwo.com/48/computer-technical-help/python-support-thread-1007515/)

jjshabado 06-02-2011 09:16 AM

Re: ** Python Support Thread **
 
Quote:

Originally Posted by Neil S (Post 26904520)
Bash IDEs all you want but please, please learn there's more to debugging than print statements. Sometimes a full debugger is overkill... but sometimes a debugger is the only way.

Indeed. If someone told me that they never used a debugger... I wouldn't work with that person.

And this is coming from someone that uses Print statements way too often.

ArturiusX 06-02-2011 10:57 AM

Re: ** Python Support Thread **
 
Quote:

Originally Posted by ralu (Post 26903907)
You do not need IDE. In case you need to debug you can use print function. This by far best and superior way for writing programs.

For simple editor you can use IDLE (it comes whit python distribution), but if you really think that you can not live without VisualStudio look like software, debugger and code completion try using Eclipse whit Pydev plugin.

What the hell? Isn't half the reason why python is awesome is the PDB module and the add-ons you can use with it? Do you really just use print statements over PDB? Really?

Aceium 06-02-2011 02:57 PM

Re: ** Python Support Thread **
 
After messing with it a bit, I figured out that I can develop .py files and then execute them directly from the cmd line. Simple!

Neil S 06-02-2011 06:13 PM

Re: ** Python Support Thread **
 
Quote:

Originally Posted by jjshabado (Post 26907325)
Indeed. If someone told me that they never used a debugger... I wouldn't work with that person.

And this is coming from someone that uses Print statements way too often.

Ditto. I'll print/NSLog/whatever all day long. But when you need the debugger.. well, just use it. It's not hard.

Slap My Jack 06-08-2011 10:19 PM

Re: ** Python Support Thread **
 
Quote:

Originally Posted by ralu (Post 26903907)
You do not need IDE. In case you need to debug you can use print function. This by far best and superior way for writing programs.

Relying on print statements for debugging anything of increasing complexity can become a bad habit, according to what I've learned.

I do agree that an IDE is not critical though, but it can be convenient. I prefer Emacs, but I also use an IDE too.

Wing IDE is a Python specific IDE that's free for non-commercial purposes. It doesn't have any overhead to setting it up (unlike Eclipse), so it can be good for beginners. And Eclipse has already been mentioned.

Aceium 06-09-2011 12:07 PM

Re: ** Python Support Thread **
 
What type of debugger do you use with Python? Is there a program that will allow you to step through instructions and inspect values along the way?

jjshabado 06-09-2011 12:08 PM

Re: ** Python Support Thread **
 
http://docs.python.org/library/pdb.html

My most common use case is just sticking:

import pdb
pdb.set_trace()

wherever I want to jump into the code.

tyler_cracker 06-10-2011 01:02 PM

Re: ** Python Support Thread **
 
ok am i losing my mind, or is this behavior just absurdly ******ed?

(yes, i appreciate the irony of my printf debugging considering the above discussion, but i'm trying to demonstrate a point.)

Code:


#!/usr/bin/env python

list = [1, 'a', 'b', 'c', 4]
for item in list:
    print "list before: %s" % list
    try:
        item = int(item)
    except ValueError:
        print "%s cannot be cast to int. Delete it." % item
        list.remove(item)
    else:
        print "%s looks like an int. No problem, mon." % item
    print "list after : %s" % list
    print

print "### final list is %s" % list

seems straightforward to me. however...

Spoiler:

Code:


list before: [1, 'a', 'b', 'c', 4]
1 looks like an int. No problem, mon.
list after : [1, 'a', 'b', 'c', 4]

list before: [1, 'a', 'b', 'c', 4]
a cannot be cast to int. Delete it.
list after : [1, 'b', 'c', 4]

list before: [1, 'b', 'c', 4]
c cannot be cast to int. Delete it.
list after : [1, 'b', 4]

### final list is [1, 'b', 4]

in other words, when i delete 'a' from list, the for loop doesn't notice and ends up skipping the next entry (since it moved back a slot after i deleted 'a'). i can draw a pointer diagram of what i think is happening if that will help :).



is there some simple workaround to this problem? do i need to make a separate clone of list for purposes of iterating? ugh, python.

Neil S 06-10-2011 01:08 PM

Re: ** Python Support Thread **
 
Messing with a list while you iterate through it is generally a bad idea, and that's not python-specific.

tyler_cracker 06-10-2011 01:15 PM

Re: ** Python Support Thread **
 
i mean, sure, i guess. i guess i don't know enough about how python handles its iterators internally to have an expectation that this would work.

that said, i feel like this pattern works fine in other languages. maybe i'm just losing my mind, as alluded to in my previous post :).

edit: adding list_copy = copy.deepcopy(list) and iterating on that seems to solve the problem. i think the real solution is to use map/apply/whatever-the-****-python-calls-it with a lambda or small function, but i don't think it will greatly improve efficiency and it will probably hurt readability.

jjshabado 06-10-2011 01:41 PM

Re: ** Python Support Thread **
 
Quote:

Originally Posted by Neil S (Post 27046205)
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.

RoundTower 06-10-2011 06:40 PM

Re: ** Python Support Thread **
 
Quote:

Originally Posted by jjshabado (Post 27046613)
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.

tyler_cracker 06-11-2011 02:54 PM

Re: ** Python Support Thread **
 
Quote:

Originally Posted by RoundTower (Post 27050676)
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.

RoundTower 06-11-2011 06:49 PM

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.

Neuge 06-11-2011 09:35 PM

Re: ** Python Support Thread **
 
Has anyone here used the C API? I'm having trouble calling a C function from another C function.

tyler_cracker 06-12-2011 01:27 AM

Re: ** Python Support Thread **
 
maybe just post some code and see if anyone bites?

Neuge 06-12-2011 02:19 PM

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.

tyler_cracker 06-12-2011 02:41 PM

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?

Neuge 06-12-2011 02:50 PM

Re: ** Python Support Thread **
 
Quote:

Originally Posted by tyler_cracker (Post 27074905)
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.

RoundTower 06-12-2011 05:55 PM

Re: ** Python Support Thread **
 
This reminds me that I shouldn't have put C on my resume.

jjshabado 06-13-2011 09:15 AM

Re: ** Python Support Thread **
 
Quote:

Originally Posted by RoundTower (Post 27050676)
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.

sorrow 06-13-2011 11:30 AM

Re: ** Python Support Thread **
 
Quote:

Originally Posted by RoundTower (Post 27063698)
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()]

jjshabado 06-13-2011 11:34 AM

Re: ** Python Support Thread **
 
That doesn't work since you can't call isdigit on an integer.

sorrow 06-13-2011 11:38 AM

Re: ** Python Support Thread **
 
Quote:

Originally Posted by jjshabado (Post 27090027)
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]

jjshabado 06-13-2011 11:44 AM

Re: ** Python Support Thread **
 
Do people feel the list comprehension is better than using filter here? Seems weird to me.


All times are GMT -4. The time now is 12:19 PM.

Powered by vBulletin®
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.

Copyright © 2008-2020, Two Plus Two Interactive