#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    6
    Rep Power
    0

    Trouble Getting Code to Work


    Hi, I am a complete newbie to IT and programming. I am learning Python on my own to apply it to Bioinformatics later.

    I have been using an interactive tutorial tailored for programming beginners found here:

    How to Think Like a Computer Scientist

    The chapter entitled "Decisions and Selection" has an interactive lab asking to write a program that approximates the value of pi. Here is a link to the lab:

    Approximate the Value of Pi


    I am having trouble with getting the counter accumulate a proper value. The return value that the interpreter yields is a float rather than an int.

    Here is what I have so far:

    Code:
    def approximate_pi(alex, numdarts):
    	"""Approximate value of pi using turtle."""
    
    	import turtle
    	import math
    	import random
    
    	wn = turtle.Screen()
    	wn.setworldcoordinates(-1, -1, 1, 1)
    
    	alex = turtle.Turtle()
    	alex.speed(1)
    	alex.penup()
    
    	for i in range(numdarts):
    		randx = random.random()
    		randy = random.random()
    
    		x = randx
    		y = randy
    
    		alex.goto(x, y)
    
    		if alex.distance(0, 0) <= 1:
    		    	alex.color('red')
    		    	alex.dot()
    		    	insideCount = 0
    		    	insideCount = insideCount + x
    
    		else:
    		    	alex.color('blue')
    		    	alex.dot()
    
    	wn.exitonclick()
    
    	return insideCount
    I am using Python 3.2

    Could somebody help me out? Thanks.
  2. #2
  3. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,905
    Rep Power
    481
    Interesting, I also couldn't make turtle.dot draw.

    alex.stamp() # marked the figure.

    alex shouldn't be an input parameter to your function.
    [code]Code tags[/code] are essential for python code and Makefiles!
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    6
    Rep Power
    0
    Originally Posted by b49P23TIvg
    Interesting, I also couldn't make turtle.dot draw.

    alex.stamp() # marked the figure.

    alex shouldn't be an input parameter to your function.
    Actually, once I played with it a bit more, I was able to get the turtle to draw the dots successfully. The edited code I posted reflects that.

    What do you mean alex should not be an input parameter? Would you mind explaining a bit more, please?


    Also, my post does not appear to provide a links to the pages any longer. If you having this problem, please let me know and I will find a way to communicate them.
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    6
    Rep Power
    0
    I've just run it a few more times in the interpreter and I noticed that I cannot generate a random number outside of the first quadrant. So any suggestions for that are also welcome. Thanks.
  8. #5
  9. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,905
    Rep Power
    481
    Code:
    def approximate_pi(alex, numdarts):
        """Approximate value of pi using turtle."""
        #...
        alex = turtle.Turtle()
    Your function does not use whatever object you passed into it as alex before reassigning it to the Turtle() object. Passing alex as a parameter is useless, slow, and confusing.

    Later in your code you have the consecutive statements
    Code:
                    insideCount = 0
                    insideCount = insideCount + x
    0 is the identity element under addition. The two statements amount effectively to
    insideCount = x
    (I'm sure that's an incorrect implementation of your pi approximation algorithm, you need to move the insideCount=0 assignment above the loop over darts.)

    You're aware that the action takes place in the first quadrant?
    [code]Code tags[/code] are essential for python code and Makefiles!
  10. #6
  11. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,905
    Rep Power
    481
    oh you are aware. Maybe you should read your own code:

    wn.setworldcoordinates(-1, -1, 1, 1)

    while random.random() returns floats from 0 to 1.

    2*random.random()-1

    or

    wn.setworldcoordinates(0,0, 1, 1)
    [code]Code tags[/code] are essential for python code and Makefiles!
  12. #7
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    6
    Rep Power
    0
    Originally Posted by b49P23TIvg
    oh you are aware. Maybe you should read your own code:

    wn.setworldcoordinates(-1, -1, 1, 1)

    while random.random() returns floats from 0 to 1.

    2*random.random()-1

    or

    wn.setworldcoordinates(0,0, 1, 1)
    Yes, as I mentioned in the first sentence, I am a complete newbie to programming. My background is Microbiology and Cell Science.

    I just read some information about the random.random() object in the Global Module Index. I read that the domain is [0, 1). That cleared up the first quadrant issue for me.
  14. #8
  15. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    6
    Rep Power
    0
    Originally Posted by b49P23TIvg
    Code:
    def approximate_pi(alex, numdarts):
        """Approximate value of pi using turtle."""
        #...
        alex = turtle.Turtle()
    Your function does not use whatever object you passed into it as alex before reassigning it to the Turtle() object. Passing alex as a parameter is useless, slow, and confusing.
    I understand what you're saying about passing "alex" as a parameter. The source I was using passes "t" as a parameter, then reassigns t = turtle.Turtle(). Frankly, I found "t" as an insufficient parameter and variable name. So I substituted "alex" instead.


    Originally Posted by b49P23TIvg
    Later in your code you have the consecutive statements
    Code:
                    insideCount = 0
                    insideCount = insideCount + x
    0 is the identity element under addition. The two statements amount effectively to
    insideCount = x
    (I'm sure that's an incorrect implementation of your pi approximation algorithm, you need to move the insideCount=0 assignment above the loop over darts.)

    You're aware that the action takes place in the first quadrant?
    Obviously, I am trying to use the insideCount as an accumulator pattern. That is where I am having my trouble precisely. Its purpose is to count the number of times that the turtle draws a dot within the 1 unit radius. You are right to say that it is ineffective at this. As it reads currently, it acts somewhat like a factorial.

    Have you any suggestions to get it to act as an accumulator?
  16. #9
  17. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,905
    Rep Power
    481
    "passing alex as a parameter is useless" I don't care what you call your variables. (Well, I do, but alex is no worse than t.) I meant this:

    def approximate_pi(numdarts):

    approximate_pi depends on numdarts. approximate_pi cannot depend on an input value of alex because it never uses that value. When you call approximate_pi call it with the one parameter. Do you think that variables used in a function must be named in the function header? No. You used `i' without writing

    def approximate_pi(numdarts,i):


    "(I'm sure that's an incorrect implementation of your pi approximation algorithm, you need to move the insideCount=0 assignment above the loop over darts.)"
    Code:
    $ python
    Python 2.7.3 (default, Sep 26 2012, 21:51:14) 
    [GCC 4.7.2] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import random
    >>> accumulation = 0   ##### SEE, accumulation precedes the loop
    >>> n = 40000
    >>> for i in range(n):
    ...   accumulation += (random.random()**2+random.random()**2) <= 1
    ... 
    >>> print(accumulation)   ## digits of pi by golly
    31490
    >>>
    [code]Code tags[/code] are essential for python code and Makefiles!
  18. #10
  19. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    6
    Rep Power
    0
    Originally Posted by b49P23TIvg
    "passing alex as a parameter is useless" I don't care what you call your variables. (Well, I do, but alex is no worse than t.) I meant this:

    def approximate_pi(numdarts):

    approximate_pi depends on numdarts. approximate_pi cannot depend on an input value of alex because it never uses that value. When you call approximate_pi call it with the one parameter. Do you think that variables used in a function must be named in the function header? No. You used `i' without writing

    def approximate_pi(numdarts,i):


    "(I'm sure that's an incorrect implementation of your pi approximation algorithm, you need to move the insideCount=0 assignment above the loop over darts.)"
    Code:
    $ python
    Python 2.7.3 (default, Sep 26 2012, 21:51:14) 
    [GCC 4.7.2] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import random
    >>> accumulation = 0   ##### SEE, accumulation precedes the loop
    >>> n = 40000
    >>> for i in range(n):
    ...   accumulation += (random.random()**2+random.random()**2) <= 1
    ... 
    >>> print(accumulation)   ## digits of pi by golly
    31490
    >>>
    Unfortunately, your suggestion does not solve the problem.

    I tried using the following code last night:

    Code:
    def approximate_pi(numdarts):
    	"""Approximate value of pi using turtle."""
    
    	import turtle
    	import math
    	import random
    
    	wn = turtle.Screen()
    	wn.setworldcoordinates(-1, -1, 1, 1)
    
    	alex = turtle.Turtle()
    	alex.speed(1)
    	alex.penup()
    
    	for i in range(numdarts):
    		randx = 2*random.random()-1
    		randy = 2*random.random()-1
    
    		x = randx
    		y = randy
    
    		alex.goto(x, y)
    
    		if alex.distance(0, 0) <= 1:
    		    	alex.color('red')
    		    	alex.dot()
    		    	
    		    	insideCount = 0
    
    		    	for x in range(numdarts):
    		    		insideCount = insideCount + x
    
    		else:
    		    	alex.color('blue')
    		    	alex.dot()
    
    	wn.exitonclick()
    
    	return insideCount
    However, even with the insideCount variable moved outside of the for loop, it was still ineffective at accumulating a proper value.

    I have also tried moving both the insideCount and for loop outside of the if statement, however, this was also ineffective.

    I have an intuition that at least part of the problem is how I am specifying the for loop.
  20. #11
  21. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,905
    Rep Power
    481

    Spoon fed


    Code:
    import turtle
    import random
    
    def approximate_pi(numdarts):
        """Approximate value of pi using turtle."""
        print('simulating %d darts'%numdarts)
        wn = turtle.Screen()
        wn.setworldcoordinates(-1, -1, 1, 1)
        alex = turtle.Turtle()
        alex.speed(10)
        alex.penup()
        insideCount = 0
        for i in range(numdarts):
            x = 2*random.random()-1
            y = 2*random.random()-1
            alex.goto(x, y)
            within = alex.distance(0,0) <= 1
            insideCount += within
            alex.dot(None,('blue','red')[within])
        return insideCount,wn
    
    n = 400
    insideCount,wn = approximate_pi(n)
    print('%d hits of %d darts'%(insideCount,n))
    print('Click the picture to terminate')
    wn.exitonclick()
    [code]Code tags[/code] are essential for python code and Makefiles!
  22. #12
  23. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,905
    Rep Power
    481

    useful


    Anyway, I'm relearning to use Cairo graphics. Here is roughly the same program in c.
    Compilation on linux for x11 and png:
    Code:
    a=./d && make -k "CFLAGS=$( pkg-config --cflags gtk+-3.0 )" "LOADLIBES=$( pkg-config --libs gtk+-3.0 )" $a && $a
    text output:
    pi digits: 314403

    Code:
    /* Copyright (c) 2012 the authors listed at the following URL, and/or
    the authors of referenced articles or incorporated external code:
    http://en.literateprograms.org/Hello_World_(C,_Cairo)?action=history&offset=20070528220552
    
    Permission is hereby granted, free of charge, to any person obtaining
    a copy of this software and associated documentation files (the
    "Software"), to deal in the Software without restriction, including
    without limitation the rights to use, copy, modify, merge, publish,
    distribute, sublicense, and/or sell copies of the Software, and to
    permit persons to whom the Software is furnished to do so, subject to
    the following conditions:
    
    The above copyright notice and this permission notice shall be
    included in all copies or substantial portions of the Software.
    
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    
    Retrieved from: http://en.literateprograms.org/Hello_World_(C,_Cairo)?oldid=10388
    */
    
    #include<cairo.h>
    #include<cairo-xlib.h>
    #include<X11/Xlib.h>
    
    #include<math.h>
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    
    #define SIZEX 512
    #define SIZEY 512
    
    #define FOREVER for(;;)
    
    void paint(cairo_surface_t *cs) {
      cairo_t *c;
      int i,n,j,last,k;
      double x[2];
      c=cairo_create(cs);
      cairo_scale(c, SIZEX/2.0, -SIZEY/2.0);
      cairo_translate(c, 1.0, -1.0);
      cairo_set_font_size(c,0.01);
      last = 2;
      for (i = n = 0; i < 400000; ++i) {
        for (k = 0; k < 2; ++k)
          x[k] = 1-2*random()/((float)(RAND_MAX));
        j = (pow(x[0],2)+pow(x[1],2)) <= 1;
        if (j != last) {
          last = j;
          cairo_set_source_rgb(c, j, 0.0, 1-j);
          cairo_fill(c);
        }
        cairo_move_to(c,x[0],x[1]);
        cairo_show_text(c,"o");
        n += j;
      }
      cairo_fill(c);
      printf("pi digits: %d\n",n);
      cairo_show_page(c);
      cairo_destroy(c);
    }
    
    void showxlib() {
      Display *dpy;
      Window rootwin;
      Window win;
      XEvent e;
      int scr;
      cairo_surface_t *cs;
      if(!(dpy=XOpenDisplay(NULL))) {
        fprintf(stderr, "ERROR: Could not open display\n");
        exit(1);
      }
      scr=DefaultScreen(dpy);
      rootwin=RootWindow(dpy,scr);
      win=XCreateSimpleWindow(dpy, rootwin, 1, 1, SIZEX, SIZEY, 0, 
    			  BlackPixel(dpy, scr), BlackPixel(dpy, scr));
      XStoreName(dpy, win, "hello");
      XSelectInput(dpy, win, ExposureMask|ButtonPressMask);
      XMapWindow(dpy, win);
      cs=cairo_xlib_surface_create(dpy, win, DefaultVisual(dpy, 0), SIZEX, SIZEY);
      FOREVER {
        XNextEvent(dpy, &e);
        if(e.type==Expose && e.xexpose.count<1)
          paint(cs);
        else if(e.type==ButtonPress) break;
      }
      cairo_surface_destroy(cs);
      XCloseDisplay(dpy);
    }
    
    void writepng(const char *fname) {
      cairo_surface_t *cs;
      cs=cairo_image_surface_create(CAIRO_FORMAT_ARGB32, SIZEX, SIZEY);
      paint(cs);
      cairo_surface_write_to_png(cs, fname);
      cairo_surface_destroy(cs);
    }
    
    int main(int argc, char *argv[]) {
      if(1<argc) writepng(argv[1]);
      else showxlib();
      return 0;
    }
    [code]Code tags[/code] are essential for python code and Makefiles!

IMN logo majestic logo threadwatch logo seochat tools logo