Monday, 18 May 2015

Python 3 - Open File Dialog Window In Tkinter With filedialog

I wanted to make a file loader for a chatbot program I am working on in Python 3 using Tkinter. I thought  that it would be a tricky task until I stumbled up the filedialoge module and the askopenfilename function.

Tkinter uses the filedialoge access the askopenfilename to open a window that matches the format of your operating system. Mine is currently Windows 8, so it looks like this.


How good does that look. To use the askopenfilename function you need to import it:
from tkinter.filedialog import askopenfilename
Because you will probably want to run the file from a command in a menu bar of from a button click it's probably a good idea to wrap it in a function:
def OpenFile():
    name = askopenfilename(initialdir="C:/Users/Batman/tkinter/",
                           filetypes =(("Text File", "*.txt"),("All Files","*.*")),
                           title = "Choose a file."
                           )
The askopenfilename function can have a number of options or no options and you can leave it blank. The ones I have used in this example I think are the most useful:

initialdir 

 set the the initial file location that the function will open it.

filetypes


This allows you set the type of files you want the user open. The end result appears in the bottom drop down menu.
First you set the file in a tuple ("Text File", "*.txt"). The first input is the title you want to name the file type(e.g. "Text File") and the second string is the file name ("*.txt"). If you have a custom file type, like ("*.noob"), then you can use that too.
What I discovered is that it requires a minimum of two file types for this option to work. So if you get an error this might be it.

title

This is the title you want to add to the top bar. 


In the below example you can execute the file in the Menu in File-Open. I thought I'd give you a realistic application of the askopenfilename.
As you can see from the first print the file does not open the document, rather it gets the file location and from there you can open and use the file. In the above example I have opened the file as a variable and then read it because I had a text file. You could as easily put the variable in a label or text widget in tkinter.

Useful Links:
http://effbot.org/tkinterbook/tkinter-file-dialogs.htm
http://tkinter.unpythonic.net/wiki/tkFileDialog

Saturday, 16 May 2015

Changing The Colour Of Selected Text In Tkinter Text Wiget In Python

I am working on a simple chatbot program using Tkinter in Python 3 and have finished all the back end.
I'm now working on making the front end look pretty.

The Problem
One of the things I wanted to do was change the colour of the chatbot's title in the text widget to make it easier to read. I thought it would be pretty easy.
My guess was that I could modify the colour from the .insert method. A little like this:

text.insert(END,'Bottity Bottity Bot Bot: '+ BotInput + '\n',foreground='red')
Fail!!!
Life isn't that easy.

The Solution
It turns out that it is quite a task to add a colour to words in a text widget in Tkinter. The best hack I could find was to modify a search and highlight function I found in Python in a Nutshell by Alex Martelli.


I had to make some changes which basically removed the search function and replaced it with a key word of the name of my chatbot, in this case: Bottity Bottity Bot Bot

Here are the results in a simple example:

As you can see, the find() function searches for my chatbot name and then changes it's foreground color in the text.tag_config('found', foreground='red') section. in tag_config you can also modify the font styles and the background.

P.S. I really like the lastidx = '%s+%dc' % (idx, len(s)) variable. This was such a clever bit of code that I spent an hour down the rabbit hole on String Formatting Operations.

Returning A Value From A Function To Be Used Outside The Function in Python 3

Functions are really useful for doing stuff for you in a program. But the hardest thing for me to work out was how to use what ever they did in the rest of my program.

Problem
Let's say I wanted to make a function to convert my string to lowercase. My program would look a little like this:

# Returns a string in lowercase
def Make_Lowercase(cmt):
cmt = cmt.lower()
comment = "My name is SCOTT."
print ("Commment without lowercase formatting:")
print (comment)
print("")
 
#Replace the old variable with the lowercase one created in the function
print ("Comment run through function to make it lowercase:")
print (cmt)
 Here I am trying to get the new comment, cmt, but when I run the program it yells at me with:
Traceback (most recent call last):
  File "C:/Users/Im/Batman/Python3/ReturnFunction.py", line 13, in <module>
    print(cmt)
NameError: name 'cmt' is not defined
Boo! I can't access the local variable inside the Make_Lowercase function.

Solution
To fix this, we need to return the variable inside the function and place the result back into the original (or a new variable. Up to you.) variable.

Here is an example:

Now we can use the results from the function outside of the function and in the rest of the program. Yay!


Removing Unwanted Whitespace in a String in Python 3

I have written a simple chatbot program in Python 3 where the user enters a comment and the bot responds. After offering it to family to play with I discovered that they would often put whitespace in front of the sentence or after. For example:

'  How are you?     '  or  'How are you? '
Problem:
The problem is that when I send this to the file to search for the match response. It comes up without a match because the string is saved as:
 'How are you?'
As you can see this has no spaces before or after. The single quotation marks. So when I run the search with it comes up with nothing and I don't really want to add unessessary lists with spaces just in case the program receives sloppy input.

Solution:
It turns our that the solution is quite simple. Python provides two simple tools to remove extra white space before and after the sentence or even duplicate spaces between words in a string.

In the first function, remove_whitespace_either_side, we use the variable.strip() method. This method essentially strips the white space from either side of the sentence in the string.

But what happens if your program user is a bit of a typing numpty and manages to put extra white spaces between the works? For example:
' I am     a typing                   numpty!'
As you can see, the first function cannot deal with this.

This is where the second function, remove_any_duplicated_white_space , is so useful. This function uses two methods forming " ".join(variable.spit()). Here, we split all the words into individual strings and then join them back together into one string with a single space between each.

You can see the result of each in the code above.

Looking at the quality of input I have been getting for my chatbot I think I will be using the second function.

Friday, 15 May 2015

Python 3 - Tkinter Scrolling with Inserted Text

I am using tkinter's ScrolledText to create a text box that I insert text in each line.

The problem
The problem was that when I inserted new text, the text box would not automatically scroll down to reveal the new text.

The solution
The solution turned out to be the yview method.

In the example below, I added while loop of 100 numbers(lines) to demonstrate that noew the text box is now focussed to the bottom of the text.

Tuesday, 2 December 2014

Russel Brand Slammed by Journalist Dina Rickman for Keeping Focussed on an Interview

Since Russell Brand developed a social and political conscience (or as least begun to share it with the public) I have been a big fan. 

He has recently been supporting the campaign to fight Westbrook Properties from massively increasing rent in order to force eviction of tenants at New Era Estate. 

In an video interview with Paraic O'Brien, Brand slams...no, that's not the right work...smashes... nope still not there...politely and respectfully...yes, much better... dresses down O'Brien for changing the direction of the discussion about the rent hikes and forced evictions of the residents of New Era Estate by asking Brand how much his home costs. 

FYI, Brand rents.

O'Brien continues to try and force some sensational confession out of Brand while, now, completely ignoring the more important issue regarding the people of the New Era Estate in Hackney.

Shitty reporting? Why yes. 

Have a look for yourself:


Enter Dina Rickman, in support of Brand and attacking O'Brein's dodgy reporting you may think. But no. She adds a new layer to the stupid with this headline:
Don't Ever Ask Russell Brand How Much His House Costs
...which he doesn't own.

Essential, in her few lines of reporting, she is attempting to lambaste Brand for putting O'Brein on point.  She was supporting O'Brein's bad reporting, which leads me to think that she does not know how to report.

I thought I would give her the benefit of the doubt and check out her other writing. Here are some of here recent highlights:

  • "Would You Want to be a Princess Nowadays?" (Oh wait, just a list of comments. No reporting going on here folks)
  • "I'm fat, so what? It's not an ugly word': Why the f-word might just finally be OK"
  • "We Need to Break The Public Hair Taboo"
Classy stuff.

I am beginning to think that we need to take a more active role in improving the media. So here is what I propose; copy and paste this message to Matthew Champion, the editor of i100 and let him know that Dina Rickman is not up to scratch:

TWITTER: @matthewchampion, I know you want a site we can trust, but @dinarickman has slipped through the cracks with this last @rustyrockets piece
Or your own creative twitter. I am sure Champion will listen, as he says:
Because i100 is from The Independent you can still trust us to take our facts very seriously (even the funny ones). Some of the stories will have been inspired by the brilliant work in the i or The Independent. Most will be from the crack team of i100 journalists.
Now, let's have a look at O'Brien. His editor, Ben de Pear, seems to be on his side with this ridiculous tweet:

@rustyrockets vocal on the rent row- but not on his own calling our @paraicobrien"snide" #NewEraEstate http://bit.ly/1FHK1sp #c4news at 7
 So perhaps even de Pear needs a little schooling on journalism. Let's hope this sinks in:

@bendepear, old @rustyrockets had to put your boy, @paraicobrien, back on topic about #NewEraEstate. You should be thanking him.
 What it all comes down to is a sub culture of shitty reporting. These are the people we rely on to get information about what is going on in our world and they are letting us down. That is why many of us are going to the internet for our news for better or worse. Perhaps we need to look at our news through the lens of sites like the Trews.

Thursday, 27 November 2014

Why are we seeing more and more protests in the western world?

We are seeing more and more protests in the western world. But why?

I don't have all the answers but I think its stems from a number of things.

First, I think the momentum got under-way as a result of the Arab Spring and Occupy movement. The protests seem to be a result of the continued frustration over the voice of the people being ignored by those in power, coupled with the continued strain on the common people via prohibitive laws or laws that breed inequality. This inequality can be between, class, races, religious practices or even between people and groups like large multinational corporations.

In recent years, we have also seen greater restrictions and management of protests. For example, you now have to get a permit to protest and you are cordoned into specific areas, usually to hide you from view of the people you wish to see your cause. Police create huge strategic plans to manage protests.

The strange thing is that this cordon and control by an outside source is completely contrary to the nature of a protest. A protest is designed to be a regaining of control by the protestees (new word). It is should be the responsibility of the protest groups to organise as best it can to get its point across. The very act of controlling a protest it the first aggressive act against the protest. Even before it hits the ground.

This control causes greater frustration by the protest group which causes them to push their cause even harder.

Secondly, we are are at a stage in our existence on Earth where our natural non-renewable resources are in rapid decline. Those that are in power are grasping for the last scraps and they will do anything to get them, like manipulate and corrupt governments. This is nothing unusual. We have seen resource declines throughout history with similar tragic effects until an alternative is found of the situation implodes.

I don't know if this is avoidable, but we have fostered a culture and political system where those who seek to gain more than others are rewarded. Once they have more they do everything in their power to stop others from gaining more and catching up. Even to the point where they will sacrifice some of their gains to prevent others from moving up. This is the very core of corruption.

This may be an effective tool in the past where you are competing for finite resources for your survival but as we are now forced to see each other less by our small groups and tribes and more as a collective member of Earth this strategy fails.

Communism was our first attempt at collective sharing but it failed to understand the highly and irrationally competitive nature of many people. This quickly led to corruption. Democracy, on the other hand understood that some people are innately corrupt and buffered for it better.

The thing is, Democracy can only buffer for so long until corruption takes hold and if Democracy starts with corruption, it is essentially a loosely hidden dictatorship of the corrupt elite and is destined to fail from the start.

What we are seeing in the Democratic world now is that the buffer has worn through and the corrupt elite are taking hold.

We are now railing against this because we see where this will lead. Thus we protest. The corrupt-elite know what's coming so they militarized the police force. They try and control protest before it even starts. They block and control the media through corporate monopolies and attempt to reign in the free flow of information (net-neutrality). And they seek to pry on our everyday lives (internet surveilance).

We see the inequality rise in our countries and know that we need to stand against it before the corruptions takes hold.

We are now understanding that we are all brothers and sisters of Earth and we seek to take responsibly for our planet and each other but are barred from doing so by the very nature of capitalistic democracy and corrupt quasi-democratic dictatorships.

Global society is in dire need of an audit. A revolution. These protests are the first salvo of this revolution and those corrupted and in power know this and are fearful. It is time for the pendulum to swing in the other direction.


... the alteration of men on a mass scale is, necessary, ... a revolution; this revolution is necessary, therefore, not only because the ruling class cannot be overthrown in any other way, but also because the class overthrowing it can only in a revolution succeed in ridding itself of all the muck of ages and become fitted to found society anew.
Karl Marx
Let's hope we can do it peacefully.