Sinisterly
Sweet Python Techniques and Advices. - Printable Version

+- Sinisterly (https://sinister.ly)
+-- Forum: Coding (https://sinister.ly/Forum-Coding)
+--- Forum: Python (https://sinister.ly/Forum-Python)
+--- Thread: Sweet Python Techniques and Advices. (/Thread-Sweet-Python-Techniques-and-Advices)

Pages: 1 2 3


Sweet Python Techniques and Advices. - L0aD1nG - 07-28-2014

Coding The Pythonic Way

Hello, [username].

In this thread I will try to show you some pythonic ways to make your python code shorter, cleaner, and maybe faster and more stable.And also some techniques that I will find intersting to share over time.Some of them may seem very simple, other may seem more advanced, depending on your personal python knowledge.
All the examples are tested on Python 2.7.3 and they work fine.

Requirement : Basic Python Knowledge.

Requirement not covered??
You are absolutely new on Python World??
Before you start take a look at this amazing Python Basics Tutorial Thread --> http://www.hackcommunity.com/Thread-Tutorial-Python-For-Beginners
Made by @Ex094 .

LET'S START!


ADVICES


Advice Number 0
Swapping variable's values.

Spoiler: View Advice

On many other languages you should do something like this:
Code:
temp = a a = b b = temp

On PYTHON the right way to do this is:
Code:
b, a = a, b




Advice Number 1
Summing a numeric iterable.

Spoiler: View Advice

The usual way to get a sum of a numeric iterable on many languages would be:
Code:
ls = [1,2,3,4] ls_sum = 0 for item in ls: ls_sum += item

On PYTHON the right way to do this is:
Code:
ls = [1,2,3,4] ls_sum = sum(ls)




Advice Number 2
Conditional check up for 0 or None or False.

Spoiler: View Advice

Some people write down simple if conditions harder than needed to:
Code:
boolFlag = 0 if boolFlag != 0 : print('Flag isn't zero') else: print('Flag is zero')

On PYTHON and generally on programming is better to avoid comparisons when you don't even need them:
Code:
boolFlag = 0 if boolFlag: print("Flag isn't zero") else: print("Flag is zero")
**NOTE --> Same would be done if we had implemented boolFlag as None or False.




Advice Number 3
String Formatting.

Spoiler: View Advice

On PYTHON you are able to do that:
Code:
string = "Mary Jane" print("My girlfriend's name is " + string)

Although there is a better way for string formatting (when its only about printing out) avoiding costy concentration:
Code:
string = 'Mary Jane' print("My girlfriend's name is %s"%string)
**NOTE --> For many variables and when its not only about strings, string method format() is the best way to go(also for more special formating features).




Advice Number 4
String Concentration.

Spoiler: View Advice

When you need to create a string from substrings the most obvious/straigt-forward way is this:
Code:
total_string = '' strings = ['I', 'love', 'you', 'Eve'] for string in strings: total_string += string + ' '

But in PYTHON the above proves to be much costly compared to a single string method:
Code:
strings = ['I', 'love', 'you', 'Eve'] total_string = ' '.join(strings)
**NOTE --> You can use any character you like for string separator for example this ','.join(strings) would end like 'I,love,you,Eve'.




Advice Number 5
Avoid len() use for empty iterable conditional check up.

Spoiler: View Advice

Its not much usual but we all have seen (and i personally was doing it too) this :
Code:
ls = [] if len(ls) == 0: print("Empty list brah!")

On PYTHON when you put empty list on if conditions its proving to be False already:
Code:
ls = [] if not ls : print("Empty list brah!")




Advice Number 6
Import Globally not Locally.

Spoiler: View Advice

It proves to be more costy to import locally:
Code:
def func(): from time import sleep for i in range(10): sleep(1)

Its better/cleaner to import everything on the top:
Code:
## Importing from time import sleep def func(): for i in range(10): sleep(1)




LOOK ADVICE 12
Advice Number 7
Use map() function when possible.

Spoiler: View Advice

We all know that looping all the time is MUCH costly, avoid looping especially when its about simple tasks:
Code:
ls = [1, 2, 3, 4] string_ls = [] for i in ls: string_ls.append(str(i))

On PYTHON using built-in function map() instead would be better:
Code:
ls = [1,2,3,4] string_ls = map(lambda item : str(item), ls)
**NOTE --> So map(function, iterable) goes like this map takes every single item of the "iterable" and executes "function" given that item as argument, at last the "function" should return a new item and finally whole map() returns a new iterable same type with "iterable".For more complex tasks its better to avoid lambda and normally define a new function to apply on map.

LOOK ADVICE 12


LOOK ADVICE 12
Advice Number 8
Use filter() function when possible.

Spoiler: View Advice
So loops can be even more costly when they contain conditional statements:
Code:
ls = [-1, -2, 3, 4] result_ls = [] for i in ls: if i > 0: result_ls.append(i)

We can avoid this using built-in filter() function:
Code:
ls = [-1, -2, 3, 4] result_ls = filter(lambda item : True if item > 0 else False, ls)
**NOTE --> So filter(function, iterable) goes like that, takes every single item from the give "iterable" pass it on the given "function" and executes the function.If the function returns False the item is removed from the iterable else if True is returned it keeps the item.At last it returns a new iterable same type with the one given (like the map does).

LOOK ADVICE 12


Advice Number 9.
Implement functions the normal way when is about permanent functions.

Spoiler: View Advice
Everybody i guess likes to use lambda when its about simple tasks:
Code:
func = lambda item: item ** 2 print(func.__name__)

But lambda functions has there disadvantages its better to use normal definitions about permanent function that will be used a lot in
your script, even when its that simple:
Code:
def func(item): return item ** 2 print(func.__name__)
**NOTE -->
Spoiler: Big Image
[Image: tGNzNQp.png]





Advice Number 10
Avoid massive usage of raw_input, every millisecond counts.

Spoiler: View Advice
The normal way to get an input is:
Code:
inp = raw_input("Give some input : ")

Although sys.stdin.readline() proves to be faster than the normal way, you just have to strip '\n' then and manually set a message:
Code:
import sys print "Give some input : ", inp = sys.stdin.readline().strip('\n')
When its about massive inputing by the user that way is preffered and in big programs can make the difference for sure

**NOTE --> Although print built-in function proves to be as fast as sys.stdout.write() so just stick with print.




Advice Number 11
Big range iterations using xrange, is much faster.

Spoiler: View Advice
The range() can be a nightmare on Python 2 when is about big iterations:
Code:
for x in range(100000000): print x

Using xrange() when its about this big iterations proves way better:
Code:
for x in xrange(100000000): print x

I counted down with ipython, an iteration over 100000000 and thats what was the result...
Spoiler: Take a look on this
[Image: ouHZHZO.png]



Furthermore it seems range() to do better as the distance of the range gets lower but xrange also proves stability on its timings...
Spoiler: Take a look on this
[Image: sIvN8kL.png]



**NOTE 0 --> Although xrange proves to be a lot better than range() it has its downfalls which leads us to range() when needed to, for example xrange() can't be used when its about real numbers {e.g. range(1,100,0.1)}Trying to do use xrange() with float will lead on this...

Spoiler:
[Image: VAFhyQU.png]



**NOTE 1 --> Speaking about xrange() downfalls I should mention that xrange() returns an generator object so you have to convert it on list.. so when its about for small list of numbers to avoid converting, its better to stick with range()




Advice Number 12
AVOID lambda functions combined with map, filter etc.

Spoiler: View Advice
I personally used them inside map, filter Advice 7 and Advice 8 wanted to give you better understanding through that way about how both functions work BUT it is proved that map, filter combined with lambda get even a little slower than for loops!

So how would we customize Advice 7 to be perfect?

Instead of doing this:
Code:
ls = [1,2,3,4] string_ls = map(lambda item : str(item), ls)

We would do this:
Code:
ls = [1,2,3,4] string_ls = map( str , ls )


**NOTE --> Best timings are proved using built-in functions with map, filter etc. but even normally defined function would work better than lambda just avoid using lambda when its about using that functions, if it seems like you can't avoid them go straight to the for loop.




Advice Number 13
Function calls are costy. Don't overuse them with no reason.

Spoiler: View Advice
Well thats simple avoid function calls as much as possible, when its about massive function calls in a loop for example:
Code:
def func(SUM, item): sum += item return sum SUM = 0 ls = [1,2,3,4] for item in ls: SUM = func(SUM, item)
Please avoid doing something like this on big programs where you do more advanced things on a function this could increase up timings..

Prefer to adapt your function to feet your needs, and make it happen in one single call:
Code:
def func(ls): sum = 0 for item in ls: sum+=item return sum ls = [1,2,3,4] sum_ls = func(ls)
This is much more decent. Avoiding massive function calls when you are able can cause you much more stability and fairly better timings.




TECHNIQUES



Technique Number 0.
Function to find and return current free RAM space as int(Linux Only).

Spoiler: View Technique
This technique require some basic Bash Scripting knowledge.
Code:
## Importing from os import popen ## Function to find current available RAM ## and return it as an int. def free_memory_finder(): ## Find total memory total = popen("free -t | grep Mem: | awk '{print $2}'") ## Find cached memory cached = popen("free -t | grep '-' | awk '{print $3}'") ## Make them integers total_memory = int(total.read()) cached_memory = int(cached.read()) ## Calculate the free memory free_memory = total_memory - cached_memory return free_memory
**NOTE --> The int number that is returned is on KB.

Explantion image, executing the commands one by one on terminal.
Spoiler: Big Image
[Image: MH0tS6E.png]





Technique Number 1.
Function to prepare geometry for a Tkinter.Tk window to be on the center of the screen.

Spoiler: View Technique

This function will bring the Tkinter to the center of the screen when the mainloop() will be casted.
Code:
## Function to set the Tk window on the center def center_widget(root, width, height): """this function is reffered only on tkinter widgets, it centerize to the screen the main widget""" ## Setting the coordinates to add on geometry set up x = (root.winfo_screenwidth() / 2) - (width / 2) y = (root.winfo_screenheight() / 2) - (height/ 2) ## Setting the correct geometry root.geometry('{0}x{1}+{2}+{3}'.format(width, height, int(x), int(y)))

Then if you run something like...
Spoiler: This
Code:
from Tkinter import Tk root = Tk() center_windget(root, 480, 320) root.mainloop()



You will probably get something like...
Spoiler: This(Big Image)
[Image: Abc9LCG.png]





Technique Number 2.
Function that returns pretty xml output.

Spoiler: View Technique
This function takes an implemented xml.etree.ElementTree.Element and returns a nice output using xml.dom.minidom.parseString class and a method of it.
Code:
## Importing from xml.dom.minidom import parseString from xml.etree.ElementTree import tostring def unglyxml_to_prettyxml(elem): """Function to make the xml output good looking, using xml.etree via xml.dom method""" ## Taking the whole elem to a string current_elem_string = tostring(elem, 'utf-8') ## Parse it to the minidom parsed_on_minidom = parseString(current_elem_string) ## Return it prettier ( on the usual xml view ) return parsed_on_minidom.toprettyxml(indent="\t")
It really help outs those who want to use xml.etree way for xml handling...

I also made an example so you can really understand why its helpful.
Spoiler: Take a look on the example
Lets create an xml element using xml.etree module:
Code:
## Importing from xml.etree import ElementTree from xml.etree.ElementTree import Element, SubElement ## Setting the root element root = Element("students") ## Initialize and create subelements ## for first subelement of the root subel0 = SubElement(root, "Class_A") SubElement(subel0, 'class_A_student', name = 'George Clinton') SubElement(subel0, 'class_A_student', name = 'Peter Suarez') ## Same for the second SubEle subel1 = SubElement(root, "Class_B") SubElement(subel1, 'class_A_student', name = 'Hillary Clinton') SubElement(subel1, 'class_A_student', name = 'Luis Suarez')
Thats a simple element with some subelements on xml.etree .

Now lets try print it out and see what we get:
Code:
## Converting the element to string object xml_string = ElementTree.tostring(root) ## Print it out print(xml_string)
Done with converting and printing.

And this is what we get...
Spoiler: Check out
[Image: ajpHi3d.png]
You can see, how bad looking it is...just look at the bar its a huge single string.




Now if we import and use the function I have mentioned on that Technique Topic:
Code:
## You will adapt the import statement, to fit you needs from Pretty_XML_output import unglyxml_to_prettyxml print(unglyxml_to_prettyxml(root))

Then this is what we get now:
Spoiler: Check out
[Image: cUe1JrI.png]






Thats all I have for now.
Also make sure you take a look at the Docstrings Conventions PEP.
Its worth the time if you are a beginner.

Okay guyz I hope you liked that techniques/advices tutorial, I also hope that my crappy english didn't bother you too much :epic:, please make a post if you are a PYTHONISTAZ and you have any suggestions, corrections, dislikes that would be very helpful for me.

With Love For HackCommunity, L0aD1nG.


This Thread Will Be Updated Over Time



RE: Sweet Python Techniques and Advices. - Psycho_Coder - 07-28-2014

Good Work there. Thanks for compiling this, though there are a lot more techniques but still these will be very beneficial to new Python Programmers Smile


RE: Sweet Python Techniques and Advices. - L0aD1nG - 07-28-2014

@Psycho_Coder
Thanks a lot dude, I know that is a few I will try to update this tutorial/thread as soon as possible with new material.


RE: Sweet Python Techniques and Advices. - L0aD1nG - 08-13-2014

A fairly good update on the thread, check it out! Some new advices and techniques added.
Let me know your opinion on these community. Kappa


RE: Sweet Python Techniques and Advices. - Psycho_Coder - 08-13-2014

for xml parsing use lxml its fast efficient and very user friendly


RE: Sweet Python Techniques and Advices. - l4ur15 - 08-13-2014

Thank you very much! That's what they don't teach you in books...


RE: Sweet Python Techniques and Advices. - h3r0 - 08-13-2014

Great resource, there are a lot of little gems in there. Thank you.


RE: Sweet Python Techniques and Advices. - h3r0 - 08-13-2014

Great resource, there are a lot of little gems in there. Thank you.


RE: Sweet Python Techniques and Advices. - L0aD1nG - 08-13-2014

(08-13-2014, 05:53 PM)Psycho_Coder Wrote: for xml parsing use lxml its fast efficient and very user friendly

I am still using etree, I must check the others sometime. But still I find etree to be very clear.

EDIT: Does lxml.etree has a tostring() method that supports "pretty_print=True" as args?


RE: Sweet Python Techniques and Advices. - L0aD1nG - 08-13-2014

(08-13-2014, 05:53 PM)Psycho_Coder Wrote: for xml parsing use lxml its fast efficient and very user friendly

I am still using etree, I must check the others sometime. But still I find etree to be very clear.

EDIT: Does lxml.etree has a tostring() method that supports "pretty_print=True" as args?