We're a community of 1077K IT Pros here for help, advice, solutions, professional growth and fun. Join us!
1,076,063 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Start New Discussion Reply to this Discussion
Page 16 of Article: Starting Python
The idea of this thread is to help the beginning Python programmer with hints and helpful code. Please feel free to contribute! If you have any questions start your own thread! The creators of Python are very active, improving the language all the time. Here is a little of the…
# intercept a wrong data type with a function decorator

def require_numeric (func):
    """decorator to check if function argument is of type int or float"""
    def wrapper (arg1, arg2=0):
        if type(arg1) == int or type(arg1) == float:
            return func(arg1)
        else:
            print("need a numeric value!")
    return wrapper

@require_numeric
def print_num(arg):
    print("numeric value = %f" % arg)

# test ...
print_num(7.33)        # numeric value = 7.330000
print_num("$3.99")  # need a numeric value!
HiHe
Posting Whiz
332 posts since Oct 2008
Reputation Points: 177
Solved Threads: 34
Skill Endorsements: 4

@HIhe
Lets be functional and generate/itertools/lambda the same:

# everyone likes TGIF
# so loop through a whole year day by day and show all the dates that are Fridays
from itertools import takewhile, count
import datetime

# pick a year
year = 2012
one_day = datetime.timedelta(days=1)
start_year = datetime.date(year, 1, 1)

print("These are all the Fridays of %d:" % year)
for day in takewhile(lambda d: d <= datetime.date(year, 12, 31), (start_year + one_day * c for c in count(0))):
    if day.weekday() == 4:
        print("%s is a Friday" % day)
pyTony
pyMod
Moderator
6,306 posts since Apr 2010
Reputation Points: 879
Solved Threads: 986
Skill Endorsements: 26

Numpy is a high speed numeric module for Python:

# use loadtxt() to load a data file to a numpy array

try:
    # Python2
    from StringIO import StringIO
except ImportError:
    # Python3
    from io import StringIO
import numpy as np

data_str = """\
1,2,3
4,5,6
"""
# create a file object
data_file = StringIO(data_str)
# load into a numpy array, default is float datatype
data_array = np.loadtxt(data_file, delimiter=',', dtype=int)

print(data_array)

'''
[[1 2 3]
 [4 5 6]]
'''

print('-'*30)

data_str2 = """\
frank,19,167
jean,18,123
"""
# create a file object
data_file2 = StringIO(data_str2)
# load mixed data types into a numpy array
dt = {
'names': ('first','age','weight'),
'formats' : ('S12','i4','i4')
}
data_array2 = np.loadtxt(data_file2, delimiter=',', dtype=dt)

print(data_array2)

'''
python2>>>
[('frank', 19, 167) ('jean', 18, 123)]
python3>>>
[(b'frank', 19, 167) (b'jean', 18, 123)]
'''
HiHe
Posting Whiz
332 posts since Oct 2008
Reputation Points: 177
Solved Threads: 34
Skill Endorsements: 4
# sum a bunch of numbers recursively

# works with Python2 and Python3
try:
    input = raw_input
except NameError:
    pass

def my_sum():
    n = input('Next number or blank to finish: ')
    return (float(n) + my_sum()) if n else 0

s = my_sum()
print("The sum of numbers is %s" % s)
HiHe
Posting Whiz
332 posts since Oct 2008
Reputation Points: 177
Solved Threads: 34
Skill Endorsements: 4
# specifically replace full words only
# will replace red but not change reduce
# like the normal string.replace() function would
# note that replacement is case sensitive
# attached quotes and punctuation marks are neutral

import re

def replacer(match_obj):
    # function will be called for each key_word
    # in the text during substitution
    word = match_obj.group(0)
    return replace_dict.get(word, word)

text = """
In this text 'debug' will be changed but not 'debugger'.
Similarly red will be replaced but not reduce.
How about Fred, -red- and red?  Red, white and blue
"""

# create a dictionary of key_word:replace_with pairs
replace_dict = {
"red" : "redish",
"debug" : "fix"
}

# a regular expression matching all identifiers
pattern = re.compile(r"[A-Za-z_]\w*")

print(pattern.sub(replacer, text))

"""result -->
In this text 'fix' will be changed but not 'debugger'.
Similarly redish will be replaced but not reduce.
How about Fred, -redish- and redish?  Red, white and blue
"""
HiHe
Posting Whiz
332 posts since Oct 2008
Reputation Points: 177
Solved Threads: 34
Skill Endorsements: 4

One way to get your IP:

# get your ip
# Python32

import urllib.request

def get_external_ip():
    '''returns a string'''
    url = "http://automation.whatismyip.com/n09230945.asp"
    ipb = urllib.request.urlopen(url).read()
    # decode <class 'bytes'> to string
    ip = ipb.decode("utf8")
    return ip

print(get_external_ip())
ZZucker
Master Poster
780 posts since Jan 2008
Reputation Points: 342
Solved Threads: 60
Skill Endorsements: 1

Time a function with a timing decorator:

# time relatively time consuming functions
# with a decorator function
# apply the decorator right above the function
# you want to time, starting with a @
# works with Python27 and Python32
# (use module timeit for faster functions)

import time

def print_timing(func):
    """set up a decorator function for timing"""
    def wrapper(*arg):
        t1 = time.time()
        res = func(*arg)
        t2 = time.time()
        print('%s took %0.3f ms' % (func.__name__, (t2-t1)*1000.0))
        return res
    return wrapper

@print_timing
def get_primes(n):
    """
    standard optimized sieve algorithm to get a list
    of prime numbers from 2 to < n, prime numbers are
    only divisible by unity and themselves
    (1 is not considered a prime number)
    """
    if n < 2:  return []
    if n == 2: return [2]
    # do only odd numbers starting at 3
    s = list(range(3, n+1, 2))
    # n**0.5 simpler than math.sqr(n)
    mroot = n ** 0.5
    half = len(s)
    i = 0
    m = 3
    while m <= mroot:
        if s[i]:
            j = (m*m-3)//2
            s[j] = 0
            while j < half:
                s[j] = 0
                j += m
        i += 1
        m = 2*i+3
    # skip all zero items in list s
    return [2]+[x for x in s if x]


print( "prime numbers from 2 to <10,000,000 using a sieve algorithm")
prime_list = get_primes(10000000)

'''my result with Python32 -->
prime numbers from 2 to <10,000,000 using a sieve algorithm
get_primes took 2632.000 ms

just a note, result with Python27 -->
get_primes took 2394.000 ms
'''
ZZucker
Master Poster
780 posts since Jan 2008
Reputation Points: 342
Solved Threads: 60
Skill Endorsements: 1

You can use lambda to set up a function:

# works with Python27 and Python32

# a recursive denary to binary function via lambda
d2b = lambda d: (not isinstance(d,int) or (d==0)) and '0' \
    or (d2b(d//2)+str(d%2))


den = 255
print("denary = %d" % den)
binary = d2b(den)
print("binary = %s" % binary)
# check reult with function bin()
print("binary = %s via bin(%d)" % (bin(den), den))

'''result -->
denary = 255
binary = 011111111
binary = 0b11111111 via bin(255)
'''
ZZucker
Master Poster
780 posts since Jan 2008
Reputation Points: 342
Solved Threads: 60
Skill Endorsements: 1

You can set up a function decorator using a class:

# using a Python class as a decorator

class StripCharacters:
    """
    a decorator class to strip given chrs from string text
    by default strip common punctuation marks --> ,.?!:;
    """
    def __init__(self, func, chrs=",.?!:;"):
        self.chrs = chrs
        self.func = func

    def __call__(self, text):
        """
        allows the class instance to be called as a function
        """
        # do the stripping
        new_text = ''.join(c for c in text if c not in self.chrs)
        return self.func(new_text)

@StripCharacters
def print_text(text):
    print(text)

text1 = 'If you are here, you are lost!'
print_text(text1)

print('-'*30)

text2 = 'common punctuation marks are ,.?!:;'
print_text(text2)

'''my result -->
If you are here you are lost
------------------------------
common punctuation marks are 
'''
ZZucker
Master Poster
780 posts since Jan 2008
Reputation Points: 342
Solved Threads: 60
Skill Endorsements: 1

You can use Python to check the size of a given directory (folder):

# determine the size of a given folder in MegaBytes

import os

# pick a folder you have ...
folder = r'C:\Python32\DLLs'

folder_size = 0
for (path, dirs, files) in os.walk(folder):
    for file in files:
        filename = os.path.join(path, file)
        folder_size += os.path.getsize(filename)

print("Folder %s = %0.1f MB" % (folder, folder_size/(1024*1024.0)))

'''possible result -->
Folder C:\Python32\DLLs = 5.6 MB
'''
ZZucker
Master Poster
780 posts since Jan 2008
Reputation Points: 342
Solved Threads: 60
Skill Endorsements: 1

Sometimes you have to flatten a deeply nested list or tuple:

# flatten a nested list

def flatten(seq):
    mylist = []
    for item in seq:
        if isinstance(item, (list, tuple)):
            # recursive function
            mylist.extend(flatten(item))
        else:
            mylist.append(item)
    return mylist

nested_list = [1, 2, [3, 4, [5, 6, [7, 8]]]]
print(nested_list)
print('nested list flattened:')
print(flatten(nested_list))

'''result-->
[1, 2, [3, 4, [5, 6, [7, 8]]]]
nested list flattened:
[1, 2, 3, 4, 5, 6, 7, 8]
'''
ZZucker
Master Poster
780 posts since Jan 2008
Reputation Points: 342
Solved Threads: 60
Skill Endorsements: 1

The Python function range() handles only integers. Here is a range generator that handles floats:

# a floating point range generator with roundoff-fix
# works with Python2 and Python3

def frange(start, stop=None, step=1.0, delta=0.0000001):
    """
    a range generator that handles floating point numbers
    uses delta fuzzy logic to avoid float rep errors
    eg. stop=6.4 --> 6.3999999999999986 would slip through
    """
    # if start is missing it defaults to zero
    if stop == None:
        stop = start
        start = 0
    # allow for decrement
    if step <= 0:
        while start > (stop + delta):
            yield start
            start += step
    else:
        while start < (stop - delta):
            yield start
            start += step

# testing ...
# expect numbers 6.0 to 6.3
for k in frange(6.0, 6.4, 0.1):
    print("%f" % k)

'''my result -->
6.000000
6.100000
6.200000
6.300000   okay!
'''
ZZucker
Master Poster
780 posts since Jan 2008
Reputation Points: 342
Solved Threads: 60
Skill Endorsements: 1

The Python function format is available for Python27 and Python3 and above ...

# create a 4 row 5 column evenly spaced table using format()
# tested with Python27 and Python32

text = """\
kamikaze pilots did wear helmets
abbreviation is a long word
shoot them in tourist season
a quarterback is a refund
"""

# create a list of the words
w = text.split()

n = 0
for k in range(0, len(w), 5):
    # Python27 and higher string formatting
    # use a field of 13 char to fit longest word
    sf = '{:13s} {:13s} {:13s} {:13s} {:13s}'    
    print(sf.format(w[n], w[n+1], w[n+2], w[n+3], w[n+4]))
    n += 5

"""
kamikaze      pilots        did           wear          helmets      
abbreviation  is            a             long          word         
shoot         them          in            tourist       season       
a             quarterback   is            a             refund    
"""
vegaseat
DaniWeb's Hypocrite
Moderator
6,475 posts since Oct 2004
Reputation Points: 1,447
Solved Threads: 1,611
Skill Endorsements: 36

Use the Python module timeit to test the speed of a function. Here is an easy way:

'''get_timing.py
use Python module timeit in a wrapper
modified vegaseat code
works with Python2 and Python3
'''

def get_timing(fs, number=10000, module="__main__"):
    """
    this wrapper can be used to time any function
    pass full function call in as a string eg. 'func(arg1, arg2)'
    number = number of timeit loops
    module namespace is autodetected
    """
    import timeit
    import inspect
    # extract function name
    q1 = fs.split('(')
    f = eval(q1[0])
    # extract arguments
    q2 = q1[1].strip(')')
    if q2:
        args = eval(q2)
    else:
        args = None
    name = f.__name__
    # get module namespace
    module = inspect.getmodule(f).__name__
    if args == None:
        st1 = "%s()" % (name)
    elif type(args) == tuple:
        st1 = "%s%s" % (name, args)
    elif type(args) == str:
        st1 = "%s('%s')" % (name, args)
    else:
        st1 = "%s(%s)" % (name, args)
    st2 = "from %s import %s" % (module, name)
    t = timeit.Timer(st1, st2)
    # elapsed time is in microseconds
    print("Function %s took %.2f microseconds/pass" % \
        (st1, 1000000*t.timeit(number=number)/number))
    # optional ...
    return eval(fs)

def gcd3(x, y):
    """greatest common denominator, non-recursive"""
    while y:
        x, y = y, x % y
    return x

def test():
    pass

# testing ...
if __name__=="__main__":
    import math

    # no arguments
    print(get_timing('test()'))

    # one argument
    print(get_timing("math.log(1000)"))

    # two arguments
    print(get_timing('gcd3(1251, 3357)'))
sneekula
Nearly a Posting Maven
2,483 posts since Oct 2006
Reputation Points: 1,000
Solved Threads: 231
Skill Endorsements: 2

Create a multidimensional array (matrix or list of lists):

# create a x by y matrix (list of lists)

import pprint

def zero_matrix(x,y):
    '''create a x rows by y columns matrix of zeroes'''
    return [[0 for a in range(y)] for b in range(x)]


# test matrix has 10 rows and 12 columns
ma = zero_matrix(10, 12)
pprint.pprint(ma)

print('-'*32)

# to test change row=0 col=0 to a 1
ma[0][0] = 1
pprint.pprint(ma)

''' result -->
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
--------------------------------
[[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]

'''
HiHe
Posting Whiz
332 posts since Oct 2008
Reputation Points: 177
Solved Threads: 34
Skill Endorsements: 4

One way to display text in color:

# display a multi-line text in your browser in color

import webbrowser as wb

def color_text_html(text, color="black"):
    # replace any newline with <BR> html code
    text = text.replace('\n', '<BR>')
    return "<FONT color=%s>%s</FONT>" % (color, text)


# this is your test text
text = """\
one
two
three
"""

# add some color html code
text_html = color_text_html(text, "red")

print(text_html)  # test

# write the text out as .htm file
fname = "simple_text.htm"
with open(fname, "w") as fout:
    fout.write(text_html)

# now display the text in your web browser
wb.open(fname)
HiHe
Posting Whiz
332 posts since Oct 2008
Reputation Points: 177
Solved Threads: 34
Skill Endorsements: 4

This shows you how to use a helper function when sorting ...

'''sort_by_last_name1.py
sort names in format "first middle last" by the last name
'''

import pprint

def by_last_name(name):
    """
    helper function to sort by last name
    assume names are "first middle last"
    """
    return name.split()[-1]

# some sample names for testing
# format is first middle last
names = """\
Fred M. Ferkel
Carolus D. Arm
Carl S. Gustafson
Ben M. Over
Rosa X. Parker
Larry Marsh
Lola Q. Zumokar
Heinrich S. W. Buzen
"""

# convert to a list
name_list = [name for name in names.split('\n') if name]

print("names unsorted:")
pprint.pprint(name_list)

print('-'*35)

print("names sorted by last name:")
pprint.pprint(sorted(name_list, key=by_last_name))

'''result >>
names unsorted:
['Fred M. Ferkel',
 'Carolus D. Arm',
 'Carl S. Gustafson',
 'Ben M. Over',
 'Rosa X. Parker',
 'Larry Marsh',
 'Lola Q. Zumokar',
 'Heinrich S. W. Buzen']
-----------------------------------
names sorted by last name:
['Carolus D. Arm',
 'Heinrich S. W. Buzen',
 'Fred M. Ferkel',
 'Carl S. Gustafson',
 'Larry Marsh',
 'Ben M. Over',
 'Rosa X. Parker',
 'Lola Q. Zumokar']
'''
vegaseat
DaniWeb's Hypocrite
Moderator
6,475 posts since Oct 2004
Reputation Points: 1,447
Solved Threads: 1,611
Skill Endorsements: 36

Windows in its infinite oddity has chosen to us the backslash '\' in its path names. However it will work with the normal slash '/' of the unix systems. in a string things like '\temp' will be interpreted as tab and 'emp'. So why not replace the '\' with '/'? Easier said than done as you will see in this example:

# experiments to convert
# r"a\b\c\d\e.aaa" to "a/b/c/d/e.aaa"

# make sure you make s a raw string
s = r"a\b\c\d\e.aaa"

# gives SyntaxError: EOL while scanning string literal
#s2 = s.replace('\', '/')
# gives SyntaxError: EOL while scanning string literal
#s2 = s.replace(r'\', '/')

# not the desired output
s2 = s.replace('\\', '/')
print(s2)  # a\b\c\d\e.aaa

# however this will work
s3 = "%r" % s
# test
print(s3)  # 'a\\b\\c\\d\\e.aaa'
# eval() converts repr back to str
s4 = eval(s3.replace(r'\\', '/'))
# success
print(s4)  # a/b/c/d/e.aaa
Lardmeister
Posting Virtuoso
1,939 posts since Mar 2007
Reputation Points: 465
Solved Threads: 72
Skill Endorsements: 5

Here is another way to do this:

# experiment to convert back slash to forward slash
# r"a\b\c\d\e.aaa" to "a/b/c/d/e.aaa"

def back2forw(c):
    '''helper function for list comprehension'''
    return (c, '/')[c == '\\']

# make sure you make s a raw string
s = r"a\b\c\d\e.aaa"

s2 = "".join([back2forw(c) for c in list(s)])  
print(s)
print(s2)

'''result >>
a\b\c\d\e.aaa
a/b/c/d/e.aaa
'''

The helper function uses True=1 and False=0

Lardmeister
Posting Virtuoso
1,939 posts since Mar 2007
Reputation Points: 465
Solved Threads: 72
Skill Endorsements: 5

This is the exploration of a toggle function using a list element as default argument:

'''toggle_function1.py
explore functions that toggle between 2 states every time they are called
'''

def toggle(x=[0]):
    '''
    toggles between True and False each time called
    '''
    x[0] = not x[0]
    return x[0]

# test
for k in range(6):
    print(toggle())

'''result >>
True
False
True
False
True
False
'''
Lardmeister
Posting Virtuoso
1,939 posts since Mar 2007
Reputation Points: 465
Solved Threads: 72
Skill Endorsements: 5

Post: Markdown Syntax: Formatting Help
 
You
View similar articles that have also been tagged:
 
© 2013 DaniWeb® LLC
Page rendered in 0.1449 seconds using 2.82MB