Gribouillis 1,391 Programming Explorer Team Colleague

See also the table of operator precedence in python http://docs.python.org/reference/expressions.html#summary.

Gribouillis 1,391 Programming Explorer Team Colleague

@tonyjv Did you try the unidecode module for Finnish ?

Gribouillis 1,391 Programming Explorer Team Colleague

I would use

Calculate = sum

instead of the above code ;)

JasonHippy commented: well played..I forgot about sum!! +2
Gribouillis 1,391 Programming Explorer Team Colleague

You must use an affine transformation

def my_random(a, b):
    r = random()
    return a + r * (b-a)

for i in range(10):
    print(my_random(-.5, .5))

"""my output --->
-0.0536919060601
-0.023605782825
-0.154141209554
-0.457966599001
-0.405941049256
0.152834817454
0.22015783989
-0.37435978827
0.0306778666216
0.253595405275
"""
Gribouillis 1,391 Programming Explorer Team Colleague

SubBitmap is a property

>>> wx._gdi.Bitmap.SubBitmap
<property object at 0x1700db8>

The function called is

>>> wx._gdi.Bitmap.SubBitmap.fget
<function GetSubBitmap at 0x17ae500>

It's also the 'im_func' of this method

>>> wx._gdi.Bitmap.GetSubBitmap
<unbound method Bitmap.GetSubBitmap>
>>> _.im_func
<function GetSubBitmap at 0x17ae500>
Gribouillis 1,391 Programming Explorer Team Colleague

Ok, last trial, can you *run* this file and *post* its output in this thread ?

# run_me.py
import os, sys, os.path

class Command(object):
    """Run a command and capture it's output string, error string and exit status"""

    def __init__(self, command):
        self.command = command 

    def run(self, shell=True):
        import subprocess as sp
        process = sp.Popen(self.command, shell = shell, stdout = sp.PIPE, stderr = sp.PIPE)
        self.pid = process.pid
        self.output, self.error = process.communicate()
        self.failed = process.returncode
        return self

    @property
    def returncode(self):
        return self.failed

def main():
    try:
        import easy_install
    except ImportError:
        print("Could not import easy_install")
        return
    com = Command("%s %s unidecode" % (sys.executable, easy_install.__file__)).run()
    if com.failed:
        print com.output
        print com.error
    else:
        try:
            import unidecode
        except ImportError:
            print("Could not import unidecode")
        else:
            print("Module unidecode is installed")

main()
TrustyTony commented: Neat Command object I could use to put command output to Tk text window +1
Gribouillis 1,391 Programming Explorer Team Colleague

I tested the procedure on windows XP. I was able to install unidecode like this

C:\Python26\python.exe C:\Python26\Lib\site-packages\easy_install.py unidecode

In a cmd.exe terminal.

Gribouillis 1,391 Programming Explorer Team Colleague

I'm still using 2.6, but I have the newest 3 installed. I don't use 3, because there aren't many modules made for it. However, I do try and use 3's syntax in 2.6 where applicable (ie print("") not print ""). I do wish that I could do one liner "for" statements with Python, but I guess that'll have to wait xP

You can also use from __future__ import print_function .

Gribouillis 1,391 Programming Explorer Team Colleague

Same reason. Most existing modules are for python 2. I prefer python 3, but I 'm using python 2.

Gribouillis 1,391 Programming Explorer Team Colleague

It's impossible, it's very easy to install. Try this

>>> import setuptools
>>>

does this work ?
If this works
1) open a windows console
2) type: easy_install unidecode
look at the printed messages. If it works, then restart a python shell and try

>>> import unidecode

if import setuptools doesn't work we are going to install setuptools first.

Gribouillis 1,391 Programming Explorer Team Colleague

Try to run this

import sys
def main():
    text = raw_input("Enter some words with polish letters:")
    print repr(text)
    print sys.version_info
    print sys.platform
    print sys.executable
main()

and post the output here between code tags.
Could you download and run unidecode ?

Gribouillis 1,391 Programming Explorer Team Colleague

What is your platform windows, linux , other ? Also what is your version of python, 2.6 ?
A good thing to do is go here http://pypi.python.org/pypi/setuptools and download and instal setuptools by following the installation instructions. Then in a console, simply type

easy_install unidecode

This works for all the modules in the Python package index (Pypi http://pypi.python.org). Then you can use the module.

Also note that the module name is not unicode but unidecode !

Gribouillis 1,391 Programming Explorer Team Colleague

I found a funny module on the web, called unidecode http://code.zemanta.com/tsolc/unidecode/ . Here is my result

>>> from unidecode import unidecode
>>> unidecode(u'ąóęśłżźćńĄÓĘŚŁŻŹĆ')
'aoeslzzcnAOESLZZC'

nice, isn't it ?

Edit: it's also in pypi: http://pypi.python.org/pypi/Unidecode

Gribouillis 1,391 Programming Explorer Team Colleague

You could write this

>>> import re
>>> re.sub(r"\w+", lambda m: m.group(0).capitalize(), "the book of my friends")
'The Book Of My Friends'

But, it's better to compile the regex first

import re
word_re = re.compile("\w+")
def _cap(match):
    return match.group(0).capitalize()

def capitalize_all(s):
    return word_re.sub(_cap, s)

print(capitalize_all("the book of my friends"))
"""my output --->
The Book Of My Friends
"""
Gribouillis 1,391 Programming Explorer Team Colleague

Can't you just do this?

for a in array:
    number = int(a)

Yes you can, but if you want to do something with the integers, you must store them somewhere.

Gribouillis 1,391 Programming Explorer Team Colleague

You can write

int_array = [ int(s) for s in array ]
Gribouillis 1,391 Programming Explorer Team Colleague

If you are using python >= 2.6, you could use the Tabular class from this post http://www.daniweb.com/code/snippet232375-2.html#post1025743 . Here is an example use

from tabular import Tabular
from random import randint

suits = "CDHS"
cvalues = list("AKQJ") + list(str(i) for i in range(2, 11))
deck = [cv + cs for cs in suits for cv in cvalues]
columns = [list() for i in range(10)]

def main():

    for c in deck:
       columns[randint(0,9)].append(c)
    height = max(len(c) for c in columns)

    table = Tabular(
                [("  %s  " % letter, "^", "{0}") for letter in "0123456789"],
                ([(c[i] if i < len(c) else "") for c in columns] for i in range(height))
            )

    print("{0}".format(table))

if __name__ == "__main__":
    main()

""" my output -->
-------------------------------------------------------------
|  0  |  1  |  2  |  3  |  4  |  5  |  6  |  7  |  8  |  9  |
-------------------------------------------------------------
| AD  | 4C  | 9D  | JC  | AC  | 2C  | JD  | QC  | KD  | 3D  |
| JS  | 8C  | JH  | 3C  | KC  | 7C  | 5D  | 5C  | QD  | 8D  |
|     | 4D  | 4H  | 6C  | 9S  | KH  | 5H  | 9C  | 6D  | 2H  |
|     | 7D  | KS  | 10C |     | 7H  | 4S  | 2D  | 10D | 6H  |
|     | AH  |     | 10H |     | 6S  | 7S  | 3H  | 8S  | 9H  |
|     | QH  |     | QS  |     | 10S |     | 8H  |     | 2S  |
|     |     |     | 5S  |     |     |     | AS  |     |     |
|     |     |     |     |     |     |     | 3S  |     |     |
-------------------------------------------------------------
"""
Gribouillis 1,391 Programming Explorer Team Colleague

You could force instance attributes to have a type using a descriptor

class TypedAttribute(object):
    def __init__(self, tp):
        self.tp = tp
        self.name = "_typedattr_%d" % id(self)

    def __get__(self, obj, objtype = None):
        if obj is None:
            return self
        return getattr(obj, self.name)

    def __set__(self, obj, value):
        if not isinstance(value, self.tp):
            raise TypeError, "invalid type %s" % type(value).__name__
        setattr(obj, self.name, value)

class A(object):
    foo = TypedAttribute(int)

a = A()

a.foo = 7
print a.foo
a.foo = "hello"
print a.foo

""" my output -->
7
Traceback (most recent call last):
  File "./tpattr.py", line 24, in <module>
    a.foo = "hello"
  File "./tpattr.py", line 14, in __set__
    raise TypeError, "invalid type %s" % type(value).__name__
TypeError: invalid type str
"""
Gribouillis 1,391 Programming Explorer Team Colleague
def maze_to_string(maze):
    return "\n".join(''.join(row) for row in maze)

print maze_to_string(Maze)

"""my output --->
####################
####################
####################
...#################
##.##..#############
##.##..##########...
##.##..##########.##
##....###########.##
##.##.######......##
##.##.######.####.##
##.##.######.####.##
#####........#######
############.#######
############.#######
############.#######
############.#######
############.#######
############.#######
############.#######
####################

# if you replace '' with ' ', you get

# # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # #
. . . # # # # # # # # # # # # # # # # #
# # . # # . . # # # # # # # # # # # # #
# # . # # . . # # # # # # # # # # . . .
# # . # # . . # # # # # # # # # # . # #
# # . . . . # # # # # # # # # # # . # #
# # . # # . # # # # # # . . . . . . # #
# # . # # . # # # # # # . # # # # . # #
# # . # # . # # # # # # . # # # # . # #
# # # # # . . . . . . . . # # # # # # #
# # # # # # # # # # # # . # # # # # # #
# # # # # # # # # # # # . # # # # # # #
# # # # # # # # # # # # . # # # # # # #
# # # # # # # # # # # # . # # # # # # #
# # # # # # # # # # # # . # # # # # # #
# # # # # # # # # # # # . # # # # # # #
# # # # # # # # # # # # . # # # # # # #
# # # # # # # # # # # # # # # # # # # #

"""
Gribouillis 1,391 Programming Explorer Team Colleague

You can use itertools.product(*array) , also if your want your result in a list, you write list(itertools.product(*array)) .

Gribouillis 1,391 Programming Explorer Team Colleague

There must be something else in your program. In principle, these 2 lines don't send anything to the console.

Gribouillis 1,391 Programming Explorer Team Colleague

Here is a better sums

def sums(n):
    total = 0
    for i in range(0, n + 1, 1):
        total += i
    return total

Note that python already has a function sum, for example

>>> sum([1, 2, 3, 4])
10
Gribouillis 1,391 Programming Explorer Team Colleague

You must rewrite openfile as

def openfile(path):
    return open(path,"r")
Gribouillis 1,391 Programming Explorer Team Colleague

You should replace line 18-23 by

files = [openfile(p) for p in paths]
deneme = files[0]. readline()
print deneme
Gribouillis 1,391 Programming Explorer Team Colleague

You should run

$ python -i test.py

It runs your program, then starts the interactive python shell. You should also have a look at python -h.

Gribouillis 1,391 Programming Explorer Team Colleague

The i in range(0, i + 1, 1) should be n .

Gribouillis 1,391 Programming Explorer Team Colleague

I agree with you that line and text manipulations are too limited to handle the problem. You can easily write python functions to transform your lines into python tuples which are much easier to handle, compare, sort, etc. For example here is a function to read the file as a sequence of tuples

def gen_items(fileobj):
    fileobj.seek(0)
    for line in fileobj:
        yield tuple(line.strip().split()

Then you could use it like this

infile = open("myfile.txt", "r")
for item in gen_items(infile):
    print(item)

And this should print a sequence of tuples like

('chr1', '11828655',  '152',  'uc001ati.1', '*',  'R',  'ND',  'ND',  'ND',  '-30',  'ND',  'ND', 'ND',  'NPPA')

So that item[7] would be the string 'ND' for example.
Conversely, you can write a function to convert a tuple to a line

def to_line(item):
    return "\t".join(item)

which you can use like this to pruduce an output file

outfile = open("output.txt")
for item in mysequence:
    outfile.write(to_line(item))
    outfile.write("\n")

The algorithm to compare the items in the different files should not be too complex. A question is the size of your files. If your files are not too big, you can load entire files as lists of items

mylist = list(gen_items(open("my_file.txt")))

and compare the lists of tuples for example.

Gribouillis 1,391 Programming Explorer Team Colleague

I have a wx app that I would like to actively debug (even after it is compiled via py2exe). Is there a way to hook all methods(without having to manually add code to each one) and have it print their names' as they execute. I've looked into both the "inspect" and "pdb" modules and have a very limited understanding of both.
Second question, is it possible to change a functions code "on the fly." ie afunction.func_code.co_code = "some compiled code". I'm just not sure how to compile the source.
-Thx

For the first question, I once wrote a small module which uses AOP (aspect oriented programming) to trace python code. To use it, you must download the aspects module http://www.cs.tut.fi/~ask/aspects/index.shtml and also save my small module (attached file) as tracepect.py. Then in your wx python program, you can write

def main():
    from tracepect import Tracer
    import aspects
    import sys
    output_file = sys.stdout # or open("my_file.txt", "w")
    t = Tracer(output_file)
    functions = [
         # put a list of the functions that you want to trace in this list, for example:
         MyFrameClass.__init__,
         MyFrameClass.OnFoo,
         MyFrameClass.OnBar,
         my_function,
         # etc
    ]
    aspects.with_wrap(t.wrapper, *functions)
    # then run your code, for example
    try:
        MyApp().mainloop()
    finally:
        output_file.close()

The module tracepect.py is only a draft, but I already found it useful in many debugging cases. The great advantage of this is that you can trace execution without modifying a single bit of your code :)

Gribouillis 1,391 Programming Explorer Team Colleague

You can use a regex for words

import re
word_re = re.compile(r"[A-Za-z]+")

def count_words(sentence):
    return word_re.subn('', sentence)[1]

print(count_words("Give me bacon and eggs, said the other man."))
Gribouillis 1,391 Programming Explorer Team Colleague

Well, that's a possibility then. I'll try it in my virtual mandriva.


However, I still wanna find out how to do it from source in Mandriva AND what the problem here is. As I said before, it is not a problem in other distributions, but in Mandriva this is always the case. Last time (Mandriva 2009.1) I had to copy some folders from another system into the /usr/lib directory (if i remember correctly) to get it to work, but I don't have those files anymore.


Any ideas?
Maybe you can tell me what's installed in your system?

I tried to install python 3 and tkinter 3 from source when Mandriva 2010 was just a few days old and the tkinter3 package was not yet available -- and it failed --, so I'm afraid I can't help you much in this. If you manage doing it (but I still think it is a waste of time), you should post your solution in the mandriva forum, because other users may be interested :)

Gribouillis 1,391 Programming Explorer Team Colleague

That's weird, I updated everything in sight and my python is still 2.64. I do see, however, a python3 package, which is not installed.

Even if you install the python3 package, your system's python remains python2.6. To use python 3, you must invoke /usr/bin/python3 instead of /usr/bin/python.

Gribouillis 1,391 Programming Explorer Team Colleague

Note that my python3 package was automatically updated January the 5th. I don't quite understand your argument. Unless you are using bleeding edge features of python, you don't usually need the latest revision of python to run your programs.

Gribouillis 1,391 Programming Explorer Team Colleague

Why are you trying to install python3 from source ? I'm running Mandriva 2010 on a 64 bits processor and I installed the packages python3 and tkinter3 with the software manager. This gave me a working python 3 with tkinter.

Python 3.1.1 (r311:74480, Jan  5 2010, 18:03:14) 
[GCC 4.4.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import tkinter
>>> tkinter.Tk()
<tkinter.Tk object at 0x250cad0>

I also ran your code and it works very well (I had to replace Tkinter by tkinter and command=quit by command=root.quit, otherwise it prints None for some reason).

Gribouillis 1,391 Programming Explorer Team Colleague

Use the interpreter !

>>> help(str.replace)
Help on method_descriptor:

replace(...)
    S.replace (old, new[, count]) -> string
    
    Return a copy of string S with all occurrences of substring
    old replaced by new.  If the optional argument count is
    given, only the first count occurrences are replaced.
Gribouillis 1,391 Programming Explorer Team Colleague

Have tried mutiple files, all with content, and still no output

content_string = open(fileName).read()
print(content_string) # <---- OUTPUT
Gribouillis 1,391 Programming Explorer Team Colleague

You must open the file

content = open(fileName).read()
Gribouillis 1,391 Programming Explorer Team Colleague

Ok, here is an example

scores = ["playerC 34", "playerA 12", "playerD 3", "playerB 10"]

first = [x.strip().split() for x in scores]
print(first) # ---> [['playerC', '34'], ['playerA', '12'], ['playerD', '3'], ['playerB', '10']]

second = [(float(x.strip().split()[-1]), i) for (i, x) in enumerate(scores)]
print(second) # ---> [(34.0, 0), (12.0, 1), (3.0, 2), (10.0, 3)]

third = sorted(second, reverse = True)
print(third) # ---> [(34.0, 0), (12.0, 1), (10.0, 3), (3.0, 2)]

fourth = [scores[i] for (x, i) in third]
print(fourth) # ---> ['playerC 34', 'playerA 12', 'playerB 10', 'playerD 3']
Gribouillis 1,391 Programming Explorer Team Colleague

The \n is still there ! You should write

line = line.rstrip("\n")
# or line = line.strip() to remove all white space at both ends
Gribouillis 1,391 Programming Explorer Team Colleague

I just attempted the first method you provided and got an error message: list indices must be integers, not tuples.
Does this have something to do with the variable names in the code you provided?

No, I edited the code since my first post. It should work now.

Gribouillis 1,391 Programming Explorer Team Colleague

Strange... try this

import os.path

#.... your code here
 line = self.confFile.readline()
        if line == '<ICON>\n':
            line = self.confFile.readline()
            line.rstrip("\n")
            if not os.path.isfile(line):
                print("FILE DOES NOT EXIST %s" % repr(line))
            icon = pygame.image.load(line)
            pygame.display.set_icon(icon)

and post the output here.

Gribouillis 1,391 Programming Explorer Team Colleague

In that case, you must first parse each line to get the score and convert it to a number. Here is how you can do this (between lines 4 and 5)

indexes = sorted((float(s.split()[-1]), i) for (i, s) in enumerate(scores))
scores = [scores[i] for (x, i) in indexes]

Another way to do this is

scores = sorted(scores, key=line_score)

where line_score is defined independently

def line_score(line):
   return float(line.rstrip().split()[-1])
Gribouillis 1,391 Programming Explorer Team Colleague

If you want to sort by name, you only need to add scores = sorted(scores) after line 4.

Gribouillis 1,391 Programming Explorer Team Colleague

You can remove the newline at the end of the line with the rstrip method. Also, you can convert a string to int using 'int'

infile = open("infile.txt", "r")
for line in infile:
    line = line.rstrip("\n") # remove the newline at the end
    try:
        line = int(line) # convert to integer if possible
    except ValueError:
        pass # conversion failed. The line is not an integer
    print repr(line) # or do something else
Gribouillis 1,391 Programming Explorer Team Colleague

If you are speaking of linux' grep command, it does not use the same regexes as python. It uses posix regular expression. You should use grep -E and see http://www.regular-expressions.info/posix.html#bre or google for more info on the supported regexes.
Another solution is to use the grin program http://pypi.python.org/pypi/grin which is a grep written in python and which uses python's regexes on the command line. On some linux systems, it's a package (you should install it with your software manager). Otherwise you should be able to install it with easy_install on the command line.
You can use the grin command like the grep command, but with a python regex. Here is the output of grin -h :

usage: grin [-h] [-v] [-i] [-A AFTER_CONTEXT] [-B BEFORE_CONTEXT] [-C CONTEXT]
            [-I INCLUDE] [-n] [-N] [-H] [--without-filename] [-l] [-L]
            [--no-color] [--use-color] [--force-color] [-s]
            [--skip-hidden-files] [-b] [--skip-backup-files] [-S]
            [--skip-hidden-dirs] [-d SKIP_DIRS] [-D] [-e SKIP_EXTS] [-E]
            [-f FILE] [-0]
            regex [files [files ...]]

Search text files for a given regex pattern.

positional arguments:
  regex                 the regular expression to search for
  files                 the files to search

optional arguments:
  -h, --help            show this help message and exit
  -v, --version         show program's version number and exit
  -i, --ignore-case     ignore case in the regex
  -A AFTER_CONTEXT, --after-context AFTER_CONTEXT
                        the number of lines of context to show after the match
                        [default=0]
  -B BEFORE_CONTEXT, --before-context BEFORE_CONTEXT
                        the number of lines of context to show before the
                        match [default=0]
  -C CONTEXT, --context CONTEXT
                        the number of …
Gribouillis 1,391 Programming Explorer Team Colleague

It's

"Please enter a number between %s and %s." % (smallestNum, largestNum)
Gribouillis 1,391 Programming Explorer Team Colleague

Your function isPrime should read

def isPrime(n):
    if (n==2):
        return True
    for counter in range(2,n):
        if n % counter == 0:
            return False
    return True

Also it's very inefficient.

Gribouillis 1,391 Programming Explorer Team Colleague

You must unindent line 6 :)

Gribouillis 1,391 Programming Explorer Team Colleague

line 10 should be total = sumDivisors(n) . Also you can speed this up by adding total += counter + n/counter when counter < n/counter and total += counter when counter == n/counter .

Gribouillis 1,391 Programming Explorer Team Colleague

If you want a better code structure, you could write parts of the structure before the details. For example

import random

def main():
    name = get_name()
    while True:
        show_menu()
        answer = get_menu_choice()
        if answer == "P":
            play_game(name)
        elif answer == "V":
            view_high_scores()
        elif answer == "Q":
            break
        else:
            print("Please choose V, P or Q")

def show_menu():
    print (''' Menu:
(V)iew High Scores
(P)lay Game
(Q)uit Game''')

def get_name():
    pass # TODO

def get_menu_choice():
    pass # TODO

def play_game(name):
    number = random.randint(1, 42)
    guessesTaken = 0
    while True:
        try:
            guess = int(raw_input('Please enter your guess, between 1 and 42: '))
        except ValueError:
            print("Your guess must be an integer !")
            continue
        guessesTaken += 1
        if guess < number:
            print 'My number is higher.'
        elif guess > number:
            print 'My number is lower.'
        else:
            print 'Good job, ' + name + '! You guessed my number in ' + guessesTaken + ' guesses!'
            return

def view_high_scores():
    pass # TODO


if __name__ == '__main__':
    main()
Simes commented: knows python very well +0
Gribouillis 1,391 Programming Explorer Team Colleague

Here is a more compact and pythonic approach

def displayHappy():
    numLimit = input("Enter a positive integer: ")
    liHappy = list(i for i in range(1, numLimit+1) if isHappy(i))
    print liHappy

    for i in range(len(liHappy)-1):
        if liHappy[i+1] - liHappy[i] == 1:
            print "lovers: %d, %d" % (liHappy[i], liHappy[i+1])

def isHappy(num):
    while not num in (1, 4):
        num = zap(num)
    return num == 1

def zap(num):
    return sum(d**2 for d in digits(num))

def digits(num):
    while num:
        num, digit = divmod(num, 10)
        yield digit

displayHappy()
vegaseat commented: yes, very pythonic +10