Gribouillis 1,391 Programming Explorer Team Colleague

API means "Application Programming Interface". When you write a piece of software, there may be a human interface (like a GUI) which allows a user to interact with your software and an API interface, which allows a user program to interact with your software. The API is usually a collection of classes and functions which constitute a library.

In the context of GUI programming (like tkinter), "binding" usually means that you attach a function to be executed to a part of a GUI (like a button or a slider), so that if the user presses the button, the function is executed. One says that the function is bound to the button.

Gribouillis 1,391 Programming Explorer Team Colleague

you should move easygui.py to site-packages. Is it the only file in the folder ?

Gribouillis 1,391 Programming Explorer Team Colleague

According to easygui's doc, you need a file easygui.py in your site-packages directory.
Note also that the doc says that using easygui with idle may lead to unpredictable results because idle is already a tkinter application.

Gribouillis 1,391 Programming Explorer Team Colleague

The correct way to do this is

elif talk_in in ("quit", "q", "exit", "x"):
    etc
Gribouillis 1,391 Programming Explorer Team Colleague

The logical and in python is the and operator, not the & which is bitwise and.

Gribouillis 1,391 Programming Explorer Team Colleague

If I have /home/doriad/Scripts/Python/
and inside I have a bunch of folders, ie Geometry, Math, Other, etc that each contain scripts (.py files), is there a way I can just add /home/doriad/Scripts/Python to PYTHONPATH and then somehow

from Geometry/Spherical import *

rather than having to add every subdirectory to the PYTHONPATH explicitly?

Thanks,
Dave

I agree with jml699, put an empty file __init__.py in the Geometry folder and then use

from Geometry.Spherical import *

I read somewhere that the file __init__.py is no longer necessary in python 3.0.

Gribouillis 1,391 Programming Explorer Team Colleague

You could start idle like this in a terminal

idle -r complicated_nonsense.py

Another way is to run python with the PYTHONSTARTUP environment variable set to the file complicated_nonsense.py. It will then be executed when you start the interpreter.

Gribouillis 1,391 Programming Explorer Team Colleague

The pickle format is encoded. If you want to output the list in plain text, you could try this

from pprint import pprint
pprint(mu1List, fileHandle)
Gribouillis 1,391 Programming Explorer Team Colleague

No, it doesn't become a global variable. It's only a value returned by the function. This allows to write

variable = find_name()

and get this returned value.

Gribouillis 1,391 Programming Explorer Team Colleague

This script should work

import re, os

pattern = re.compile("(\+|\-)?\d+\.txt")

def find_name():
  folder = "C:/Users/Sam/Desktop"
  for filename in os.walk(folder).next()[2]:
    if pattern.match(filename):
      return filename

def main():
  filename = find_name()
  number = int(filename[:-4])
  newname = str(number-1) + ".txt"
  os.rename(filename, newname)
  print("file %s renamed %s" % (filename, newname))

main()

You could improve the idea by storing the date where you're going to leave high school and compute automatically the remaining number of days.

Gribouillis 1,391 Programming Explorer Team Colleague

You could as well use a regex like this

import re
pattern = re.compile("J=(\d+)")
def Digit(line):
    match = pattern.search(line)
    if match is None:
        return 0
    else:
        return len(match.group(1))

print (Digit("28 J=5202,5204,7497,7498 SEC=WALL1"))
print (Digit("1185 J=289,3875,2673 SEC=SLAB2"))

"""
my output --->
4
3
Gribouillis 1,391 Programming Explorer Team Colleague

Your function will compute the fibonacci sequence but it's not iterative, it's recursive (the function fib calls itself). If you want to write an iterative function, you must work with a pair of numbers x(n), y(n) = fib(n), fib(n-1). Now you should be able to write a formula which gives the pair x(n), y(n) if you know x(n-1), y(n-1). Also note that you know x(1), y(1).

Gribouillis 1,391 Programming Explorer Team Colleague

And don't forget to read this announcement about homework.

Gribouillis 1,391 Programming Explorer Team Colleague
Gribouillis 1,391 Programming Explorer Team Colleague

I think the code should look like this

def half_adder(i1, i2):
    o1 = # put your formula here
    o2 = # put your formula here
    return o1, o2

Your formulas don't match the table in the wikipedia page (where True is 1 and False is 0)

Gribouillis 1,391 Programming Explorer Team Colleague

You probably made a mistake when you copied the text. Note that the line containing return starts with 4 spaces.

Gribouillis 1,391 Programming Explorer Team Colleague

Try this

# python >= 2.5
def isLeapYear(year):
    return False if year % 4 else True if year % 100 else not year % 400

:)

Gribouillis 1,391 Programming Explorer Team Colleague

In this wikipedia page, you have a description of a half adder I think A, B, C, S are your variables i1, i2, o1, o2. There is a table showing all possible inputs and outputs.

Gribouillis 1,391 Programming Explorer Team Colleague

You must reinitialize consonant_string before each word.

Gribouillis 1,391 Programming Explorer Team Colleague

I suggest this

...
    for k,  word in enumerate(response):
        ...
        word += "ay"
        response[k] = word
    return " ".join(response)

The problem is that your code modifies the variable 'word', but not the strings stored in the list. For example

>>> L = ["hello", "world"]
>>> word = L[0]
>>> word += "way"
>>> print(L) # L was not modified
['hello', 'world']

but if we add L[0] = word before print(L) , we get the correct result.

Gribouillis 1,391 Programming Explorer Team Colleague

You can't use print as an expression before 3.0. In 3.0 you can write

doTrueFunction() if booleanValue else print("No, it's false")

before 3.0, you could write

doTrueFunction() if booleanValue else sys.stdout.write("No, it's false\n")

The problem with the syntax

[expressionA(), expressionB()][bool(expressionC())]

is that all 3 expressions are evaluated before the choice is made.

Gribouillis 1,391 Programming Explorer Team Colleague

Starting with python 2.5, you can write

print("You Win!" if playerWins else "You lose!")

The syntax is value = expressionA if conditionExpression else expressionB . Note that the condition is always computed first, and only one of A an B is executed.

shadwickman commented: great explanation of the syntax! +2
Gribouillis 1,391 Programming Explorer Team Colleague

I think the problem is in your arguments list for Popen:

>>> cmd = "awk '{print $0}'"
>>> cmd.split(' ')
['awk', "'{print", "$0}'"]

It should be ['awk', "'{print $0}'"] .

Gribouillis 1,391 Programming Explorer Team Colleague

You can use the 'index' method

>>> line = '<b>(words only):</b><font color= "#0000FF"> BABY MILESTONES</font><br /><br />'
>>> line.index("B")
44
>>> line.index("<", 44)  # 44 is the number of chars before BABY MILESTONES
59
>>> line[44:59]
'BABY MILESTONES'
Gribouillis 1,391 Programming Explorer Team Colleague

Yes there is

def search(l, key):
    if l:
        if l[0] == key:
            return 0
        s = search(l[1:], key)
        if s is not False:
            return s + 1
    return False

However, the good way to do this is to use the builtin index function !

Gribouillis 1,391 Programming Explorer Team Colleague

Sneekula's way is probably the simplest if you don't want to use 'join'. If you were working with python 3.0 (which is obviously not the case), you could write

L = ['a', 'b', 'c', 'd', 'e']
for x in L:
    print(x, end= '')
print()

which would print abcde.
Before 3.0, the equivalent is

import sys
L = ['a', 'b', 'c', 'd', 'e']
for x in L:
    sys.stdout.write(x)
print
Gribouillis 1,391 Programming Explorer Team Colleague

There are many ways to do this. One of them is to append your characters to a list instead of printing them directly. Then you join the list items with an empty string and you print the result.

alph = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p',\
            'q','r','s','t','u','v','w','x','y','z']
num =[2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7,7,8,8,8,9,9,9,9]

phone = raw_input('enter phone number in the format xxx-xxx-xxxx ').lower()

accumulator = []
index = 0
for index in range(len(phone)):
    if phone[index].isalpha():
        accumulator.append(num[alph.index(phone[index])])
    else:
        accumulator.append(phone[index])
print ''.join(accumulator)
Gribouillis 1,391 Programming Explorer Team Colleague

You should set your environment variable PYTHONSTARTUP to your file. See http://docs.python.org/using/cmdline.html#envvar-PYTHONSTARTUP

Gribouillis 1,391 Programming Explorer Team Colleague

Couldn't you try to use a timer to close the object returned by urlopen after a certain time ? For example

from urllib2 import urlopen
from threading import Timer
url = "http://www.python.org"
fh = urlopen(url)
t = timer(20.0, fh.close)
t.start()
data = fh.read()

I suppose that the fh.read() should raise an exception when fh.close is called by the timer. I can't test it because I dont know a site slow enough.

Gribouillis 1,391 Programming Explorer Team Colleague

This source code seems to contain other solutions http://code.google.com/p/timeout-urllib2/source/browse/trunk/timeout_urllib2.py.

Also the urllib module in python 3.0 (and may be 2.6?) seems to accept a timeout parameter for urlopen.

Gribouillis 1,391 Programming Explorer Team Colleague

I found the error: the (\d)+ in the pattern should have been (\d+) . I corrected it in the previous post ! So the code failed with ID's having more than 1 digit.

Gribouillis 1,391 Programming Explorer Team Colleague

Here is a new version. I tested it with the files that you gave before and it works. It doesn't load the files. Try it with more substantial input :)

import re
pattern = re.compile(r"(\d+)\s+(\w+)\s+")

class FileTwo(object):
  def __init__(self, pathTwo):
    self.path = pathTwo
    self.ifile = open(pathTwo)
    self.pos = dict()
    # read the file and create a dictionary  ID -> position in file
    curpos = self.ifile.tell()
    while True:
      line = self.ifile.readline()
      if not line:
	break
      if not line.strip():
	continue
      index = line.index(" ")
      ID = int(line[:index])
      if ID in self.pos:
	raise Exception("ID %d appears twice in file '%s'" % (ID, self.path))
      self.pos[ID] = curpos
      curpos = self.ifile.tell()
  def __getitem__(self, ID):
    # self[ID] returns the line corresponding to the given ID
    if ID not in self.pos:
      raise Exception("ID %d doesn't exist in file '%s'" % (ID, self.path))
    self.ifile.seek(self.pos[ID])
    return self.ifile.readline().strip()

def merge(pathOne, pathTwo, pathOut):
  file2 = FileTwo(pathTwo)
  out = open(pathOut, "w")
  try:
    for line in open(pathOne):
      index = line.index(" ")
      ID = int(line[:index])
      line2 = file2[ID]
      match = pattern.match(line2)
      rest = line2[match.end():]
      out.write("%s %s\n" % (line.strip(), rest))
  finally:
    out.close()

if __name__ == "__main__":
  merge("one.txt", "two.txt", "out.txt")
Gribouillis 1,391 Programming Explorer Team Colleague

I see the mistake I made. I didn't consider the 3rd item, for example in 3 Germany WW , I forget to take the WW into account. I'll modify the program. However, if file2 can have up to 700 colmuns, we could try not to load the whole content in mermory. For this, the question is:
are the files sorted ?

Gribouillis 1,391 Programming Explorer Team Colleague

You can obtain a dictionary for each line like this

def lineTodic(line):
    return dict(item.split("=") for item in (x for x in line.strip().split()))

apparently, this should work for all the lines containing = in your file. This is not exactly the dictionary that you described, but you can then update the dictionary of the first line with the dictionary of the second line, etc.

Gribouillis 1,391 Programming Explorer Team Colleague

There are different questions:
1/ does each country have a unique ID number ?
2/ does each ID number apply to a unique country ?
3/ does each country appear only once in file two ?
4/ does each country from file one have a record in file two ?
A possible modification is to use the country's name as the dictionary key (you replace dic[e.number] = e by dic[e.name] = e and mapping[number] by mapping[country] . Depending on the answers to the above questions, other things could be modified.

Gribouillis 1,391 Programming Explorer Team Colleague

You don't even need regexes: your file is 'object orientated' ;)
I fact in your file, there is a list of 'blocks'. Each block has a headline (the 1st line) and the other lines are lists of pairs key/value which can be readily transformed into dictionaries (2 pairs are separated by a space char, and the '=' char separates the key from the value). All you need to parse your file is 'strip()' and 'split()'.

Gribouillis 1,391 Programming Explorer Team Colleague

sorry, change the function to

def createMapping(pathTwo):
    source = open(pathTwo)
    dic = dict()
    for line in source:
        e = Entry(line)
        dic[e.number] = e
    return dic
Gribouillis 1,391 Programming Explorer Team Colleague

Well, first in both files, each line starts with a number which seems to identify the country, then the country name, then the rest. First write a function to parse a line

import re
pattern = re.compile(r"(\d)+\s+(\w+)")

def parseLine(line):
    "returns a triple (country_number, country_name, rest)"
    match = pattern.match(line)
    return match.group(1), match.group(2), line[match.end():].strip()

Now since file 2 has only 2000 lines, it's content can be loaded into memory. We create a mapping country_number --> entry with the second file (we could also take the country name as the key, but let's assume that the number is unique for each country)

def createMapping(pathTwo):
    source = open(pathTwo)
    dic = dict()
    for line in source:
        dic[number] = Entry(line)
    return dic

class Entry(object):
    def __init__(self, line):
        self.number, self.name, self.data = parseLine(line)

Now we read the other file, and for each line read, we complete the line using our dictionary and we write to an output file

def merge(pathOne, pathTwo, pathOut):
    mapping = createMapping(pathTwo)
    source = open(pathOne)
    out = open(pathOut, "w")
    for line in source:
        number, country, rest = parseLine(line)
        if not number in mapping:
           raise Exception("unkown country number '%s'" % line.strip())
        out.write(line.strip())
        out.write(" ")
        out.write(mapping[number].data)
        out.write("\n")

if __name__ == "__main__":
    merge("one.txt", "two.txt", "out.txt")
Gribouillis 1,391 Programming Explorer Team Colleague

If you want to write non reversible python code, you could encrypt the python code and decrypt it at run time with a non reversible C++ encryption routine.

Gribouillis 1,391 Programming Explorer Team Colleague

In python, some objects are "iterable" They can be used in "for" constructs

# this syntax is possible if the object X is iterable
for item in X:
    dothis()

Iterable objects usually have a method __iter__ which is called when you write the expression iter(X) . This method (or this expression) return an "iterator".
An iterator Z has a method "next" which returns the next item in an iteration. If there is no such item, the method next raises the exception StopIteration. An iterator also has a method __iter__ which returns itself.
Here is an example

>>> L = list(range(3))
>>> L
[0, 1, 2]
>>> Z = iter(L)  # a list is iterable
>>> Z  # Z is an iterator
<listiterator object at 0xb7d586ac>
>>> Z.next()
0
>>> Z.next()
1
>>> Z.next()
2
>>> Z.next()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>> Z is iter(Z)  # iter is a no-op on iterators
True

A file object f opened for reading is iterable. iter(f) returns an iterator over the lines of the file (without the trailing newlines (unlike readline)).

Gribouillis 1,391 Programming Explorer Team Colleague

sorry, replace f = open(filename) by f = iter(open(filename)) .

Gribouillis 1,391 Programming Explorer Team Colleague

You can do it this way

def rec_paths(file_name):
    f = open(file_name)
    for line in f:
        if 'path' in line:
            x, y = f.next(), f.next()
            return (x, y)

This will return a pair containing the 2 lines after the first line containing 'path', or None if there is no such line. Also if there is less than 2 lines after 'path', this will raise a StopIteration exception.

EDIT: strip and rstrip return a new string. A string is immutable in python: it cannot be modified by a function.

Gribouillis 1,391 Programming Explorer Team Colleague

There is also line = line[:-1] to remove the last character.
I think vegaseat meant the indentation of your python source code. It's better to indent your code with space characters instead of tab characters. You should configure your editor so that it prints 4 space characters when you hit the tab key (4 is standard, other values are possible).

Gribouillis 1,391 Programming Explorer Team Colleague

It's because when python reads a file, it has a position in the file and it reads from this position. After the call to open, the position is at the beginning of the file, but after readlines(), the position is at the end of the file. You could do this

>>> f = open(....)
>>> beginning = f.tell() # get the current position
>>> f.readlines() # read the whole file
>>> f.seek(beginning)  # go back to the beginning
>>> f.readlines() # should produce the same result as the first readlines()

in principle, seek accepts any value that was returned by a previous tell.

Gribouillis 1,391 Programming Explorer Team Colleague

I think the problem is that you misspelled the def receive , so that you defined a recieve function.

Gribouillis 1,391 Programming Explorer Team Colleague

Well, 1) list is the name of a standard type in python (the type of list objects). A type is just a particular kind of object. 2) Since list is a standard name, it should be avoided as the name of a variable (it's not an error, but it's a bad idea), so the list that you're using in your function should be given another name, like plist . 3) Assuming you do this, the variable plist is local to the function's body. It doesn't exist in the global namespace. Note that your function doesn't return any value, so a good idea would be to add an instruction return plist at the end of the body. 4) Assuming you do this, you can then write plist = prime_target(target) at global level, and this defines a global variable plist (which could be given another name). You can then compute sum(plist) !

Gribouillis 1,391 Programming Explorer Team Colleague

Perhaps you should check this link http://drj11.wordpress.com/2007/05/14/python-how-is-sysstdoutencoding-chosen/ and change the environment variable LC_CTYPE (you should also check if you can change it in your program, using os.environ ). I can't test your problem here, because I'm having a french configuration, so the é prints well. By the way, if this is french, there is only one f in "café".

Gribouillis 1,391 Programming Explorer Team Colleague

I posted recently a piece of code where I read the output of a subprocess using a non blocking socket instead of a pipe (linux only, but should work on cygwin). Perhaps you could try this technique http://www.daniweb.com/forums/post777876-19.html. There is also a nice link, which I posted in the same thread, and which could be useful for your problem http://code.activestate.com/recipes/440554/. Hope that helps :)

Gribouillis 1,391 Programming Explorer Team Colleague

May be this will work

try:
  range = xrange
except NameError:
  pass

def filenames():
  for i in range(1, 1001):
    yield "output%d" % (i * 10000)

def average_list():
  result = [0.0] * 101
  cntfiles = 0
  for name in filenames():
    cntfiles += 1
    file_in = open(name)
    for index, line in enumerate(file_in):
      key, value = line.strip().split()
      result[index] += float(value)
  for i in range(len(result)):
    result[i] /= cntfiles
  return result

print average_list()
Gribouillis 1,391 Programming Explorer Team Colleague

Grib, thanks for your help. I am still getting "None" as the output though. Here is the snippet: I have verified that the source is coming through ok.

rating_source = fetchsource(pagelink)
soup = BeautifulSoup(rating_source)
ratingregexp = re.compile(r"^[^/]*/10$")
rating_element = soup.find(ratingregexp)
print rating_element

It worked for me with this

source = fetchsource("http://www.imdb.com/title/tt0071853/")
soup = BeautifulSoup(source)
ratingregexp = re.compile(r"^[^/]*/10$")
rating_element = soup.find("b", text=ratingregexp)
print rating_element

I think the error was in the call to soup.find.