histogram in python

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • asong84
    New Member
    • Oct 2011
    • 3

    histogram in python

    I want to draw a histogram of 2-11 and each bar of the number would reach up to the chain length of that number.
    I have a hailstone sequence as given below

    Code:
    import string
    # from graphics import *
    from graphics import *
     
    #Constant
    MAX = 10000
     
    # printing functions
     
    # this function prints a brief description of the program to the user
    # Inputs: none
    # Outputs : none
    def printGreeting():
        print ""
        print " This program finds hailstones sequences of numbers"
        print " you choose. The next number in the sequence if found by"
        print " either dividing it by two(if even) or multiplying by 3"
        print " and adding 1(if odd).The program quits when the last"
        print " number in the sequence is 1\n"
     
    # this functions prints the menu for the user 
    # Inputs: none
    # Outputs : none
    def printMenu():
        print "\n\tHere are your menu choices:"
        print "\n\tI - view squence for an individual value\n"
        print "\tR - veiw sequence for range of values\n"
        print "\tL - Find the longest chain\n"
        print "\tH - Print out the histogram\n"
        print "\tQ - Quit\n\n"
     
    # end of printing funtions
     
     
    # hailstone(number) prints the hailstone sequence
    # Inputs: number
    # Outputs: none
    def hailstone(n):
     
        length = 1
        print n,
        # checks if n is not sential 
        while n != 1:
     
            # if even, divide by 2 (rule). add 1 to length
            if n % 2 == 0:
                n = n / 2
                print "->",n,
                length = length + 1
     
            # if odd, multiply by 3, add 1 (rule). add 1 to length
            elif n % 2 != 0:
                n = ( 3 * n ) + 1
                print "->",n,
                length = length + 1
     
        # print the length at the end of each chain
        print "; length =",length
        print "----------------------------------------------------------------",
        print "--------------\n"
        return length
     
    # this function returns the length of each chain from the starting number, n
    # Inputs : n
    # Outputs : none
    def chain(n):
     
        length = 1
        while n != 1:
     
            # if even, divide by 2 (rule). add 1 to length
            if n % 2 == 0:
                n = n / 2
                length  = length + 1
     
            # if even, divide by 2 (rule). add 1 to length
            elif n % 2 != 0:
                n = ( 3 * n ) + 1
                length = length + 1
        return length
     
    # getValidInt() prompts the user to enter an integer in the specified range,
    # rejects values not in that range by requiring new input, and only returns
    # a valid integer.
    # Inputs: the question of the prompt,
    #         the minimum value in the range
    #         and the maximum value in the range
    # Output: an integer in the specified range
    def getValidInt(question, min, max):
     
        # use a bad value to enter the loop
        value = max + 1
     
        # compose the prompt 
        prompt = question + " (" + str(min) + "-" + str(max) + "): "
     
        # continue to get values until the user enters a valid one
        while value == "" or value < min or value > max:
            value = raw_input(prompt)
            if len(value) != 0:
                value = int(value)
     
        # return a valid value
        return value
     
     
    # this function finds the longest chain
    # Inputs: none
    # Outputs : none
    def longChain():
         begin = "Please enter the begining integer for the range"
         end = "Please enter the ending integer for the range"
     
         # calls to getValidInt for starting and ending values
         beginNum = getValidInt(begin, 1, MAX)
         endNum = getValidInt(end, beginNum + 1, MAX)
     
         largestChain = beginNum
     
         for i in range(beginNum, endNum+1):
             if largestChain <= chain(i):
                 largestChain = i
                 length = chain(i)
     
         print largestChain, " had the longest chain ", length
     
    # this function finds the longest chain***************************8
    # Inputs: none*************
    # Outputs : none    
    def histogram():
        # initialize variables  
        longestLength = 1
        list = []
     
        start = input("Please enter the begining integer for the range: ")
        for n in range (start, start + 10):
            length = chain(n)
            list.append(length)
            if longestLength <= chain(n):
                longestLength = n
                length = chain(n)
            print longestLength
            print list
     
    def main():
     
        # prints the greeting to the user
        printGreeting()
     
        # prints the menu to the user
        printMenu()
     
        # asks user the menu choice
        choice = raw_input("Please enter your choice : ").upper()
     
        # checks to see if choice entered is from the menu
        while choice != 'Q': 
     
            # if choice is "I" or "i", proceeds to follow the individual steps
            if choice == 'I':
                n = input("Please enter your integer (1-10000):")
                hailstone(n)
     
            # if choice is "R" or "r", proceds print each number and its sequence
            # until the last number is 1, uses getValidInt to get valid integers
            # for the function
            elif choice == 'R':
     
                begin = "Please enter the begining integer for the range"
                end = "Please enter the ending integer for the range"
     
                # calls to getValidInt for starting and ending values
                beginNum = getValidInt(begin, 1, MAX)
                endNum = getValidInt(end, beginNum + 1, MAX)
     
                # for loop to get the values between starting and ending value
                for n in range(beginNum,endNum+1):
     
                    #call to the hailstone function
                    hailstone(n)
     
            # if choice is "L" or "l", proceeds to use getValidInt again to get the
            # range, error checks on the range, and then calls the function chain
            # to determine the length. 
            elif choice == 'L':
                # call to function longchain
                longChain()
     
            elif choice == 'H':
                histogram()
     
            # if niether of the menu choices, then it prints that the
            # entered text is not a valid choices
            else:
                print choice, "is not a valid choice"
     
            # prints the menu to the user
            printMenu()
     
            # asks user the menu choice
            choice = raw_input("Please enter your choice : ").upper()
     
    main()
    but how can i draw a histogram of 2-11 and each bar of the number would reach up to the chain length of that number inside this hailstone sequence.
    Last edited by bvdet; Nov 2 '11, 01:51 AM. Reason: Add code tags
  • Glenton
    Recognized Expert Contributor
    • Nov 2008
    • 391

    #2
    Using matplotlib is probably the best way to do graphing including histograms.

    Comment

    • bvdet
      Recognized Expert Specialist
      • Oct 2006
      • 2851

      #3
      Calculate the chains for each number 2 through 11 and save in a dictionary. In Tkinter, you could create a canvas with an X and Y axis on the bottom and left respectively. The X axis would be labeled 2 through 11 and the Y axis would be labeled to match the height of the longest chain. Create rectangles for each number 2 through 11 with an appropriate width for display and height to match the chain length (obtained from the dictionary) multiplied by a factor for an appropriate display.

      Comment

      • Glenton
        Recognized Expert Contributor
        • Nov 2008
        • 391

        #4
        You could do it that way, but matplotlib is an excellent way to plot graphs. It's used for publications and is very flexible. Here's a link to a histogram demo.

        There is another possibility which is to use gnuplot, and gnuplot.py to control it from your programme.

        Comment

        • asong84
          New Member
          • Oct 2011
          • 3

          #5
          we want to allow the user to draw histograms for more than one range of numbers during the running of the program, we'll want to close the window after having enough time to view it. You should close the window after 10 seconds. You'll need to use sleep() to do this.
          All handling of the graphics window should be done within the drawHistogram() function. In fact, since the window is opened in this function, it is local to this function. Trying to close the window in main() will cause an error when run.

          Comment

          • bvdet
            Recognized Expert Specialist
            • Oct 2006
            • 2851

            #6
            Glenton - I'm sure you are right, but I wanted to outline how I would do it in Tkinter. I know about matplotlib but have never used it.

            asong84 - If using Tkinter, I recommend using widget method after() instead of time.sleep().

            Comment

            • dwblas
              Recognized Expert Contributor
              • May 2008
              • 626

              #7
              A histogram is just rectangles, usually with different fill colors. The following code does not make sense, at least to me, so take a look at the comments.
              Code:
              def histogram():
                   # initialize variables  
                   longestLength = 1
                   ## list is already used by python to convert something to 
                   ## a list, so always use another name
                   list = []           
                   start = input("Please enter the begining integer for the range: ")
                   for n in range (start, start + 10):
              
                       ## You call the same chain(n) 3 times in this function
                       ## which doesn't make much sense.  Use "length" instead
                       length = chain(n)
                       list.append(length)
                       if longestLength <= chain(n): # chain(n)=length so longestLength <= length
                           longestLength = n
                           length = chain(n)    ## you already did this
                       print longestLength
                       print list

              Comment

              • asong84
                New Member
                • Oct 2011
                • 3

                #8
                dwblas i have already made that changes already, i am now trying to figure out how to make a histogram of chainlength n.
                Glenton- am still trying out the matplotlib.will get back to you if i have a problem.

                Comment

                Working...