1

I'm trying to put 2 Tkinter programs together. One gets all occurrences of each letter from a user-inputted URL and displays the count for each letter in a textbox. The other is a turtle module that creates a histogram. I would like to have occurrences of each letter be displayed as a histogram, with labels of the letters on the x-axis.

This is the code I have for both:

from tkinter import *
import tkinter.messagebox
import urllib.request
import turtle

counts = 0

def main():
    analyzeFile(url.get())
    list = [counts]
    drawHistogram(list)

def analyzeFile(url):
    try:
        infile = urllib.request.urlopen(url)
        s = str(infile.read().decode()) # Read the content as string from the URL

        counts = countLetters(s.lower())

        infile.close() # Close file
    except ValueError:
        tkinter.messagebox.showwarning("Analyze URL", 
                                    "URL " + url + " does not exist")

def countLetters(s): 
    counts = 26 * [0] # Create and initialize counts
    for ch in s:
        if ch.isalpha():
            counts[ord(ch) - ord('a')] += 1
    return counts

def drawHistogram(list):
    WIDTH = 400
    HEIGHT = 300

    raw_turtle.penup()
    raw_turtle.goto(-WIDTH / 2, -HEIGHT / 2)
    raw_turtle.pendown()
    raw_turtle.forward(WIDTH)

    widthOfBar = WIDTH / len(list)

    for i in range(len(list)):
        height = list[i] * HEIGHT / max(list)
        drawABar(-WIDTH / 2 + i * widthOfBar,
            -HEIGHT / 2, widthOfBar, height)

    raw_turtle.hideturtle()

def drawABar(i, j, widthOfBar, height):
    raw_turtle.penup()
    raw_turtle.goto(i, j)
    raw_turtle.setheading(90)
    raw_turtle.pendown()

    raw_turtle.forward(height)
    raw_turtle.right(90)
    raw_turtle.forward(widthOfBar)
    raw_turtle.right(90)
    raw_turtle.forward(height)

window = Tk()
window.title("Occurrence of Letters in a Histogram from URL")

frame1 = Frame(window)
frame1.pack()

scrollbar = Scrollbar(frame1)
scrollbar.pack(side = RIGHT, fill = Y)

canvas = tkinter.Canvas(frame1, width=450, height=450)
raw_turtle = turtle.RawTurtle(canvas)

scrollbar.config(command = canvas.yview)
canvas.config( yscrollcommand=scrollbar.set)
canvas.pack()

frame2 = Frame(window)
frame2.pack()

Label(frame2, text = "Enter a URL: ").pack(side = LEFT)
url = StringVar()
Entry(frame2, width = 50, textvariable = url).pack(side = LEFT)
Button(frame2, text = "Show Result", command = main).pack(side = LEFT)

window.mainloop()

Starting from def main(): is the histogram part. How do I combine these so that the histogram shows up in place of the textbox? Thanks in advance for any input!

Edit: enter image description here

annabananana7
  • 181
  • 7
  • 18

1 Answers1

2

You can use RawTurtle (see this topic for details). So, define raw_turtle in your code:

canvas = tkinter.Canvas(frame1, width=450, height=450)
raw_turtle = turtle.RawTurtle(canvas)

and use it for histogram. Full code will look like this:

from tkinter import *
import tkinter.messagebox
import urllib.request
import turtle


def main():
    counts = analyzeFile(url.get())
    drawHistogram(counts)

def analyzeFile(url):
    try:
        infile = urllib.request.urlopen(url)
        s = str(infile.read().decode()) # Read the content as string from the URL

        counts = countLetters(s.lower())

        infile.close() # Close file
    except ValueError:
        tkinter.messagebox.showwarning("Analyze URL",
            "URL " + url + " does not exist")

    return counts

def countLetters(s):
    counts = 26 * [0] # Create and initialize counts
    for ch in s:
        if ch.isalpha():
            counts[ord(ch) - ord('a')] += 1
    return counts

def drawHistogram(list):

    WIDTH = 400
    HEIGHT = 300

    raw_turtle.penup()
    raw_turtle.goto(-WIDTH / 2, -HEIGHT / 2)
    raw_turtle.pendown()
    raw_turtle.forward(WIDTH)

    widthOfBar = WIDTH / len(list)

    for i in range(len(list)):
        height = list[i] * HEIGHT / max(list)
        drawABar(-WIDTH / 2 + i * widthOfBar,
            -HEIGHT / 2, widthOfBar, height, letter_number=i)

    raw_turtle.hideturtle()

def drawABar(i, j, widthOfBar, height, letter_number):
    alf='abcdefghijklmnopqrstuvwxyz'
    raw_turtle.penup()
    raw_turtle.goto(i+2, j-20)

    #sign letter on histogram
    raw_turtle.write(alf[letter_number])
    raw_turtle.goto(i, j)

    raw_turtle.setheading(90)
    raw_turtle.pendown()


    raw_turtle.forward(height)
    raw_turtle.right(90)
    raw_turtle.forward(widthOfBar)
    raw_turtle.right(90)
    raw_turtle.forward(height)

window = Tk()
window.title("Occurrence of Letters in a Histogram from URL")

frame1 = Frame(window)
frame1.pack()

scrollbar = Scrollbar(frame1)
scrollbar.pack(side = RIGHT, fill = Y)

canvas = tkinter.Canvas(frame1, width=450, height=450)
raw_turtle = turtle.RawTurtle(canvas)

scrollbar.config(command = canvas.yview)
canvas.config( yscrollcommand=scrollbar.set)
canvas.pack()

frame2 = Frame(window)
frame2.pack()

Label(frame2, text = "Enter a URL: ").pack(side = LEFT)
url = StringVar()
Entry(frame2, width = 50, textvariable = url).pack(side = LEFT)
Button(frame2, text = "Show Result", command = main).pack(side = LEFT)

window.mainloop()

This topic about using scrollbars on a canvas also may be useful.

Edit
When I run the above code, I see this: enter image description here

Community
  • 1
  • 1
NorthCat
  • 9,643
  • 16
  • 47
  • 50
  • Ok, I see the turtle on the canvas now, but how come I don't see the `Label`, `Entry`, or `Button` widgets? – annabananana7 Jun 21 '14 at 03:36
  • @annabananana7 Hmm. When I run above code, I see all wingets. I added screenshot. – NorthCat Jun 21 '14 at 07:04
  • I added my screenshot, that's all I'm seeing =\ – annabananana7 Jun 21 '14 at 16:21
  • @annabananana7 Ok, try to reduce `canvas` size. For example: `canvas = tkinter.Canvas(frame1, width=450, height=450)` – NorthCat Jun 21 '14 at 20:20
  • Thanks, I can see all widgets now. I'm trying to tweak my code so that it'll read a URL and come back with the counts of letters on that website and draw the histogram. I have updated my code to what I have so far and included a screenshot of what it should look like – annabananana7 Jun 21 '14 at 20:35
  • @annabananana7 I fixed you code. I removed global `counts` and modified follow functions: `analyzeFile`, `drawHistogram` and `drawABar`. – NorthCat Jun 21 '14 at 21:07
  • It looks so cool haha thanks so much for your help! Amazing what coding can do – annabananana7 Jun 21 '14 at 21:16
  • I tried running your code, since I am using Python 2.7 , I changed urllib to urllib2. But I still get an error that url doesn't exist. Can you suggest why this is happening? – Anuradha Feb 25 '15 at 10:55