[Tutor] Python Extensions in C

James Reynolds eire1130 at gmail.com
Thu Jun 2 15:48:50 CEST 2011


I fixed it. I find if I sleep on things I have a better chance at fixing
them. Maybe I will get some real work done today instead of going all OCD on
this side project?

Here's the dif: http://pastebin.com/KYBab3H9

I'll address your points in a second, but here's how I found the problem
(Python is so much easier to work with, it's scary).

1. I thought to myself last night, I knew there was a problem with the sums
not adding up properly in the var() function (the sumall variable).

2. I then thought to myself, well, let me trace out every last variable in
the first step. I then found that sumall was being raised to the third
power, not the second power.

3. I traced out "moment" and it indeed was sending through a "3", or at
least seemed to be.

4. Meanwhile, back at line 362, I am calling the same function, but with "3"
in the moment arg.

5. It occurs to me that I need to save the value of the address that the
pointer returned from "return_varp" to a variable. I actually have such a
variable already, but just below the "third moment". The skew function now
seems to work correctly. My guess is Kurt is still broken, but most likely
this is the same problem.

I guess what happens is, the static variable in var() func is saving the
value to the same exact address. Thinking back on it, this would be
consistent with Python itself if I was to have a class like Class A(): a = 1
def update_a: A.a +=1. After calling update_a, if I print A.a my answer
should be 2.

But, what I was thinking was that each new call to var() would be like a
instance of class A above, in other words, it would create a static variable
called "temp_r", but in thinking about it, this isn't the case. Declaring
something static means (please correct me if I'm wrong) that the address you
using for "temp_r" is now and forever will be the address assigned
when initially created. So, any pointer pointing to this address will return
its changing content, whether intended to do so or not.

The entire reason why I was using static variables in the those functions
was so they didn't lose their values when returned to their calling
functions.

So anyway, back to your points.

I had gone through must of it to bring it in line with your suggestions from
earlier, but I'm afraid you caught me getting lazy.

This section:


                avg = *return_avgp;
                samp = 0;
                return_varp = var(seq, count, &avg, samp, 2);
                third_moment = var(seq, count, &avg, 0, 3);

Was an artifact from troubleshooting. It should have been (and I think is
now) how you suggested.


So at any rate, thank you for the help and if you see something else, please
don't hesitate to point it out!





On Wed, Jun 1, 2011 at 8:40 PM, ALAN GAULD <alan.gauld at btinternet.com>wrote:

> OK, It seems to have grown a bit! :-)
>
> Your use of static seems a little odd. In particular the definition of avg
> as a static double.
> You then never use avg except here:
>
>
>    1.                 avg = *return_avgp;
>    2.                 samp = 0;
>    3.                 return_varp = var(seq, count, &avg, samp, 2);
>    4.                 third_moment = var(seq, count, &avg, 0, 3);
>
> You assign the content of a pointer to avg then take use address
> of avg in var() - effectively making avg back into a pointer?
>
> Why not just use *return_avgp inside the var() function?
> And why is avg static? - do you understand what static is doing?
> And the side effects of that? Is there a reason to use static?
> If so its a bit too subtle for me...
>
> BTW, On style issues:
> While I prefer the braces style you have made the mistake of mixing styles,
>
> particularly confusing when done inside a single function as in the middle
> of
> stat_kurt()
>
> And I don't personally like variables being declared in the middle of code.
>
> (eg lines 365 and 430) I can just about accept at the start of a block,
> but I prefer at the start of the function. It's just easier to find if they
>
> are all together.
>
> Other than that I can't see the error, but its late and thats
> quite a lot of code for a Python programmer to wade through! :-)
>
>
> Alan Gauld
> Author of the Learn To Program website
>
> http://www.alan-g.me.uk/
>
>
> ------------------------------
> *From:* James Reynolds <eire1130 at gmail.com>
> *To:* Alan Gauld <alan.gauld at btinternet.com>
> *Cc:* tutor at python.org
> *Sent:* Wednesday, 1 June, 2011 20:49:44
>
> *Subject:* Re: [Tutor] Python Extensions in C
>
> So I've been continuing with my experiment above, and I've made some good
> progress and learned some new things as I've been going. I've expanded it
> out a little bit, and you can see the code here:
>
> http://pastebin.com/gnW4xQNv
>
> <http://pastebin.com/iCNJVyKr>I've tried to incorporate most of your
> suggestions (although, the code itself looks more condensed in my editor
> than what it appears there).
>
> Unfortunately, I am stuck and I have no clue how to free myself from the
> mud.
>
>
> On line 370, you will notice I have "*return_varp" as the return value and
> not "skew". This is because I am trying to figure out why the variance
> function is not working properly from this function call.
>
> Earlier today it was working fine, so I know it works at least in theory.
>
> When variance is called from stats.var it works just fine and the output is
> as expected.
>
> so for example,
>
> a = [1,2,3,4,4,5]
> stats.var(a) = 2.16 (correct)
>
> stats.skew(a) = -0.74 (not correct)
>
> Again, for this I have the return value of skew set to show me the the
> second moment. Skew is calling the same exact function as var and with the
> same exact same inputs as var(), or should be.
>
> I've looked at every single variable in variance to see what is going on
> and here is what I know for now:
>
> 1. sumall is adding up to the wrong number when called from skew (or kurt).
> 2. avg, count, and moment all are what they should be.
> 3. The sequence passed is always the same from Python (a = [1,2,3,4,4,5])
>
> I'm guessing this is some nuance of C code dealing static variables or
> something to do with memory, but again, I no even less about C than I do
> about Python (which is my objective here - learning some of this should make
> me better at both, hopefully)
>
> A couple other points: There are three parameters now, not one. The later
> two are optional. they are (list, avg, and sample) sample is True by
> default.
>
> So you can pass it an average already.
>
> Lastly, any other pointers would be greatly appreciated.
>
> James
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> On Thu, May 26, 2011 at 7:50 PM, Alan Gauld <alan.gauld at btinternet.com>wrote:
>
>>
>> "James Reynolds" <eire1130 at gmail.com> wrote
>>
>>
>>  As far as the null point goes, it shouldn't be null at all once it gets
>>> to
>>> the point Alan pointed out. The pointer is set in (for example) stat_avg
>>>
>>>   seq = PySequence_Fast(obj, "Expected a Sequence");
>>>
>>
>> Can the function fail? If so what does it return? That was
>> my point. Can seq ever still be NULL after the function call?
>> For example if the function is allocating memory it could fail
>> to grab enough and then return a NULL....
>>
>> But it depends on how reliable the Python function is in
>> its return value...
>>
>>
>>  But maybe I am missing something that you have seen?
>>>
>>
>> Don't rely on functio  returns being valid values.
>> It is common practice in industrial strength C to return a NULL
>> and expect the user to check. Manyb of the standard library
>> functions work that way too.
>>
>> So you often see code like
>>
>> if (foo = someFunction() ){   // notice it is an assignment not equality
>> test
>>     process(foo);
>> }
>>
>> HTH,
>>
>>
>> --
>> Alan Gauld
>> Author of the Learn to Program web site
>> http://www.alan-g.me.uk/
>>
>>
>> _______________________________________________
>> Tutor maillist  -  Tutor at python.org
>> To unsubscribe or change subscription options:
>> http://mail.python.org/mailman/listinfo/tutor
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20110602/6ea09998/attachment-0001.html>


More information about the Tutor mailing list