Gribouillis 1,391 Programming Explorer Team Colleague

I just read the article but still have a couple of questions. In the article, "In this case parse_args() will place all arguments in a tuple. I.e. after we run parse_args(), opt.multi will be a tuple containing all arguments that user has passed to our program."

1. So if I need to get the arguments in the program, can we just use a=opt.multi[1], b=opt.multi[2] etc?
2. If I want to have an optional argument in the end, e.g. without this argument program should proceed another way, is optparse working in this situation?

Thanks a lot!

1. tuples are numbered from 0, so it will be opt.multi[0] and opt.multi[1]. Note that one seldom needs options with multiple arguments.
2. If you mean an argument which is not part of an option, your program must examine the content of the list args in opt, args = parser.parse_args() .

Write a few test scripts to experiment with optparse, it's the best way to see how it works.

Gribouillis 1,391 Programming Explorer Team Colleague

Okay...so I understand that you don't recommend variables if loops are to be involved.

However, I have to use a bit of variables here, perhaps, to indicate doubles form 1 to 9 vertically. So if input looks like this:

123456789
222222222

from the raw_input statements

num_1 = str(raw_input("Enter set 1: ")
num_2 = str(raw_input("Enter set 2: ")

Then an error should appear for the second vertical. (Number 2 happened twice vertically there, should be only once for all rows)

So to design this code, i appended variables to indicate the vertical grid:

vertical_0 = num_1[0] + num_2[0]
vertical_1 = num_1[1] + num_2[1]#<--this is where the double 2s occured in the above eg

###...code continues to vertical_8, which is the 9th vertical column.

But like you said, variables does not work well with loops, is there a simpler bypass around this, I am a begginner here so I do feel sort of silly...

As I said, you should use lists to store the user's input. You can build rows and columns like this

rows = list()
for i in range(8):
    rows.append(raw_input("Enter row number %d: " % (i+1))
cols = list()
for j in range(len(rows[0])):
    cols.append(''.join(row[j] for row in rows))

print rows
print cols

Perhaps you should check that all rows have the same length before building the columns.

Gribouillis 1,391 Programming Explorer Team Colleague

What if I want to evaluate that each input has exactly five characters, if not, then error using a second loop for a second error message...Meaning how to I integrate a second for loop statement to read out the listed input and not mess up the first for loop?

Write pseudocode first to build the sequence of necessary actions. There are different ways to do it

for i, line in enumerate(num):
  if line i has first kind of error:
    print line i has the first error
  if line i has the second kind of error:
    print line i has the second kind of error

or

for i, line in enumerate(num):
  if line i has first kind of error:
    print line i has the first error
for i, line in enumerate(num)
  if line i has the second kind of error:
    print line i has the second kind of error

You could even define a list of possible errors and iterate over this list

Gribouillis 1,391 Programming Explorer Team Colleague

You should use optparse. There is an excellent tutorial here http://www.alexonlinux.com/pythons-optparse-for-human-beings . Also note that in recent versions of python, optparse has been replaced by a module named argparse, but I never used it yet :). Optparse is very simple.

Gribouillis 1,391 Programming Explorer Team Colleague

A universal trick is to avoid numbered variables like num_1, num_2, but rather have a list 'num' and access the data as num[0], num[1]. This allows you to write loops. So you would have

num = list()
for i in range(2):
    num.append(str(raw_input("Enter set %d: " % (i+1))))
errors = [i for (i, line) in enumerate(num) if not only(line)]
if errors:
  print "Error: sets %s are invalid." % str(tuple(i+1 for i in errors))
Gribouillis 1,391 Programming Explorer Team Colleague

Why don't you try the algorithm explained above ? I would write

def mulPoly(lst1, lst2):
    if isZeroPoly(lst1):
        return []
    else:
        return addPoly(
            mulPoly(shiftRight(lst1), shiftLeft(lst2),
            scalePoly(constCoef(lst1), lst2)
        )
Gribouillis 1,391 Programming Explorer Team Colleague

Damn.. Now i see where sleeping in lectures leads ;/

And another, and I hope the last question..

I need to select numbers bigger than average (51) from the same list and assign to new list e.g. new_list = [numbers >51].

Ok, here it is

new_list = [ x for x in L if x > 51 ]

Read the section about list comprehensions in the python documentation.

Gribouillis 1,391 Programming Explorer Team Colleague

I have another question about counting so i'll use this theme for it.

I have nubers list = [85, 25, 56, 11, 57, 52, 47, 72, 11, 94];

Average is 51 and need to count how many numbers from this list are bigger than average. How can I do this?

In python, the boolean True has integer value 1, so you can write

>>> L = [85, 25, 56, 11, 57, 52, 47, 72, 11, 94]
>>> sum((x > 51) for x in L)
6
Gribouillis 1,391 Programming Explorer Team Colleague

How about separate list for tuples of broken lines and line number where it was (add one to get it 1-based)? enumerate might be usefull for the for loop. It is frustrating thoug for user if he misentered line 3 that he must continue entering other 27 to correct the previous line (especially with input as readable as string of numbers without breaks).

If there are many numbers to enter, it's better to read them from an input file, or popup a reeditable text window.

Gribouillis 1,391 Programming Explorer Team Colleague

Yes you can store several lines of input in a list before starting to work on them

numlist = list()
for i in range(1,3):
     numlist.append(str(raw_input("Enter row " + str(i-1) + ": ")))
# then check the content of numlist

Note that in the case of 3 numbers, it could be easier to read them once on
a single line, separated by spaces or commas.

Gribouillis 1,391 Programming Explorer Team Colleague

Hi,

Thanks for the help. But I'm wondering why the import is necessary. Also, I am wondering what

end=' '

does.

Cheers,
Testie

In python 2, the print statement print 'a', 'b' prints a space between a and b. To learn about python 3's print function (and the meaning of the sep argument), read this http://docs.python.org/py3k/library/functions.html?highlight=builtin%20functions#print

Note that you can't use the print statement and the print function in the same file, and also that imports from __future__ must come before any other statement in the file. In python 3 there is no print statement.

Gribouillis 1,391 Programming Explorer Team Colleague

Here is my code. It doesn't work without importing the future print_function.

# python 2 and 3
from __future__ import print_function

def sequenceprint2(s):
    for i in range(len(s)):
        for j in range(i):
            print(s[j], end='')
        print(s[i])

print("-"*10)
sequenceprint2("dani")
print("-"*10)

""" my output -->
----------
d
da
dan
dani
----------
"""
Gribouillis 1,391 Programming Explorer Team Colleague

You can print the characters one by one. Post your code, I'll post mine :)

Gribouillis 1,391 Programming Explorer Team Colleague

If there is only 1 pair, you should get the value with

value = varBinds[0][1]

This value's type is probably this Integer class http://twistedsnmp.sourceforge.net/pydoc/pysnmp.asn1.univ.html#Integer or a similar class. Since the class has an __int__ method, you should be able to convert it directly to a python int:

n = int(value)
Gribouillis 1,391 Programming Explorer Team Colleague

DOn't you need to pass a flag to ./configure, like --enable-shared ? Check your configure options.

Gribouillis 1,391 Programming Explorer Team Colleague

Here is a possibility

print "You have decided to attack the giant rat."
        ratHP = 100
        while ratHP > 0:
            dmg = min(ratHP, random.randrange(1, 10, 1))
            print "you did %d damge to the rat, giving it %d left" % (dmg, ratHP-dmg)
            ratHP -= dmg
        print "The rat is dead !"
Gribouillis 1,391 Programming Explorer Team Colleague

Define a score function for the list items, and sort the list according to this score function

# python 2 and 3
def score(item):
    return int(item[1])

mylist = [('DcaUiVb_B09398-10', 0), ('DcaUiVb_B09398-11', 5), ('m3sui_R66441-35', 0), ('fairuz', 0), ('shukor', 6)]
print(sorted(mylist, key=score, reverse=True))
Gribouillis 1,391 Programming Explorer Team Colleague

This session of the python interpreter should enlight you

>>> grades = raw_input("Enter grades:")
Enter grades:10, 4, 4, 2
>>> print grades
10, 4, 4, 2
>>> # grades is a string (str). To examine it we print its repr
... 
>>> print repr(grades)
'10, 4, 4, 2'
>>> # the string is separated by commas. Let's split it
... 
>>> gradelist = grades.split(",")
>>> print gradelist
['10', ' 4', ' 4', ' 2']
>>> # gradelist is a list of strings. Some of them have white space
... # around the numbers. Let's remove this white space
... 
>>> gradelist = [s.strip() for s in gradelist]
>>> print gradelist
['10', '4', '4', '2']
>>> # now let's convert these strings to floating point numbers
... 
>>> gradelist = [float(s) for s in gradelist]
>>> print gradelist
[10.0, 4.0, 4.0, 2.0]
>>> # let's sum these numbers
... 
>>> bigsum = sum(gradelist)
>>> print bigsum
20.0
>>> # what is the number of grades ?
... 
>>> print len(gradelist)
4
>>> # let's compute the average
... 
>>> average = bigsum/len(gradelist)
>>> print average
5.0
vegaseat commented: nice +13
Gribouillis 1,391 Programming Explorer Team Colleague

Maybe something like this:

import os
for textfile in (filename for filename in os.listdir(os.curdir) if filename.endswith('.txt')):
    oklines = [line for line in open(textfile) if not (1569 < float(line.split()[0]) < 1575)]
    with open(textfile,'w') as outfile:
        outfile.write(''.join(oklines))

Hey tony, this is a beginner's question, not the obfuscated python contest !

Gribouillis 1,391 Programming Explorer Team Colleague

You can also write Z = [x+y for x in X for y in Y] .

vegaseat commented: sweet +13
Gribouillis 1,391 Programming Explorer Team Colleague

That's not working either. What is the assert doing?

why do you say it's not working ? It's working for me and python 2.6 or 3.1. The assert checks that the resulting list is H - H H - H - H.

Gribouillis 1,391 Programming Explorer Team Colleague

I suggest

#python 2 and 3

change2 = list('abcdefabc')
atom = list('acd')

atomset = set(atom)
h = ['H' if x in atomset else '-' for x in change2]

assert(''.join(h) == 'H-HH--H-H')
Gribouillis 1,391 Programming Explorer Team Colleague

Thats right! I have to update Ubuntu. I forgot that was yesterday.

I wonder why we don't yet have python 2.7 on our linux distributions.I have python 2.6.5 in Mandriva 2010. It may not last long: I read that the Mandriva company is dying and there was a fork of the linux distro recently called mageia (see http://www.mageia.org/en/). :(

Gribouillis 1,391 Programming Explorer Team Colleague

It's a bad idea to try to upgrade your python installation on a linux system. Don't do it, because the system uses a specific python version to run. What you can do is install several versions of python. Currently, linux systems have 2 python packages: the package which comes with the distribution (2.5 in your case) and a package python3. You can install python3 with your package manager (it will coexist with your python 2.5 and the command will be 'python3' instead of python). If you want to install python 2.6 or 2.7, you must do it from the python source code with a ./configure - make - make altinstall sequence (note the altinstall). You should probably better not do it because you will have new problems with some libraries that are not yet installed on your system, etc. Python 2.5 is very good, try to work with it.

Gribouillis 1,391 Programming Explorer Team Colleague

When it gets into recursion, j and i should change, right? p_value is always one of numbers 1-7. Thanks and I will try to get more code on.

i and j cannot change upon recursion because python functions are always called by value.

Gribouillis 1,391 Programming Explorer Team Colleague

The first problem I see is that the values of i and j are never modified, so I don't know how you can leave the loop while (i>4 and j>4) . Also if you could add some more code so that it would be runnable, that would help.

Gribouillis 1,391 Programming Explorer Team Colleague

Pleas, learn about code tags here http://www.daniweb.com/forums/announcement.php?f=8&announcementid=3 and repost your code accordingly.

Gribouillis 1,391 Programming Explorer Team Colleague

thanks for the replies...the n in my code shoul be substituted with 1,2 3,.......upto 15

Did you try

for n in range(1,16):
    subprocess.call(
        'snmpset -v2c -c arct1c 192.168.5.157 .1.3.6.1.4.1.18489.1.2.1.5.1.2.0 i %d' % n,
        shell = True)

?

Gribouillis 1,391 Programming Explorer Team Colleague

I'm not exactly sure on how this works. Can you please elaborate? Thanks a lot.

My main problem is how the exec statement really work and why is it name in self.__dict__, and how the functions got appended into the Unifier object

It's easy to understand. A statement like from socket import * is always executed
in a namespace, and the symbols of module socket are added to this namespace. The namespace can
be any dictionary. When you write this in your program, the namespace is usually the namespace of
the current module, but you can write

D = dict()
exec "from socket import *" in D

and the symbols from the socket module are added to the dictionary D instead of the current namespace.
In the Unifier class, I add the symbols to the Unifier instance's __dict__ dictionary,
so that the symbols can be accessed as the instance's attributes.
Here is a better Unifier class where you can unify with module names or other unifier objects

# python 2
"""module modunifier.py"""

class Unifier(object):
    """Unifier(*items) -> a new unifier object.

    @items: a sequence of (possibly compound) module names or Unifier instances.
    All the modules exportable names become attributes of the unifier object.
    
    """
    def __init__(self, *items):
        self += items
    def __iadd__(self, items):
        for item in items:
            if isinstance(item, Unifier):
                self.__dict__.update(item.__dict__)
            else:
                # if python 3, replace this by builtin function exec.
                exec "from %s import *" % item in self.__dict__
        return self …
Gribouillis 1,391 Programming Explorer Team Colleague

I don't know the command snmpset, but the 'n' in your call should probably be n (without quotes). Also the '-c arct1c' should be split in '-c', 'arct1c'.

Gribouillis 1,391 Programming Explorer Team Colleague

With 101 heroes, there are 79 208 745 possible teams of 5. (101*100*99*98*97)/(5*4*3*2*1). Take a look at the itertools.combinations() function (which could be named 'teams' as well!).

Gribouillis 1,391 Programming Explorer Team Colleague

Actually, browsing the source code of unununium shows mainly asm files ...

Gribouillis 1,391 Programming Explorer Team Colleague

There once was a project to build an operating system in python (unununium) see http://unununium.org/. You could browse their source code as a first step. Also you can google for "writing an operating system". There are many links.

Gribouillis 1,391 Programming Explorer Team Colleague

The problem is that functions in a and b can be dynamic and up to n amount of functions, even the filenames can be dynamic.

and they all need to be unified.

Then create a specialized class

# python 2
class Unifier(object):
    def __init__(self, *module_names):
        self += module_names
    def __iadd__(self, module_names):
        for name in module_names:
            # if python 3, replace this by builtin function exec.
            exec "from %s import *" % name in self.__dict__
        return self

Then you can write

c = Unifier("a", "b")
# or
c = Unifier()
c += ["a", "b", "os.path"]

Warning: this may fail in the very unlikely case when one of the modules contains a function __iadd__.

TrustyTony commented: Looks wicked! +2
Gribouillis 1,391 Programming Explorer Team Colleague

This thread is very long, perhaps you should start a new one ?

Gribouillis 1,391 Programming Explorer Team Colleague

I think few people know this detach() method which is new in python 3. The answer is in the specification of the class of the returned stream. A pythonic way to do is to try to read from the stream: if it fails, it means that you can't read :)

Also note that if you want to write python 2 compatible code, you should avoid 'detach'.

Gribouillis 1,391 Programming Explorer Team Colleague

You could start writing the sequence of actions and loops that the computer should do, like "create a deck", "shuffle the deck", "get input", "if input is Enter", etc. Write a flow chart on a sheet of paper. (Also what will your program do if the user enters "Ebter" or "ENTER" ?).

Gribouillis 1,391 Programming Explorer Team Colleague

First, don't use the names of fundamental data types (like dict and list) as variable names. You could write

mydict = {}

for line in file:
  
    mydesc,myword = [w.strip() for w in line.split(',')]
    if myword in mydict:
        mydict[myword].append(mydesc)
    else:
        mydict[myword] = [mydesc,]
Gribouillis 1,391 Programming Explorer Team Colleague

There was an old solution on linux to kill a subprocess

# linux, mac
os.kill(pid, signal.SIGKILL)
killedpid, stat = os.waitpid(pid, os.WNOHANG)
if killedpid == 0:
    print >> sys.stderr, "ACK! PROCESS NOT KILLED?"

however the Popen.terminate() method is more recent and probably does about the same. Also what you can do is try to read the stdout and stderr of your subprocess while it is running. I once found a very simple method to do this in linux. See this post http://www.daniweb.com/forums/post777876.html#post777876.

Gribouillis 1,391 Programming Explorer Team Colleague

I think you should put the full path at line 37 in your code

shutil.move(path, dst_file)

Also I think you should sort date_file_list only after the loop for file in glob.glob... .

Gribouillis 1,391 Programming Explorer Team Colleague

Your question is much too vague. You should describe the content of your file and the 'formula' that you want to apply. A general pattern to handle several lines of data is

def handle_line(line):
    pass # do whatever you want with a line here

for line in open("myfile.txt"):
    handle_line(line)
Gribouillis 1,391 Programming Explorer Team Colleague

In a loop, the iter method is called: see this experiment

>>> x = xrange(10)
>>> x
xrange(10)
>>> y = iter(x)
>>> y
<rangeiterator object at 0x7fcbaaff2ed0>
>>> y.next
<method-wrapper 'next' of rangeiterator object at 0x7fcbaaff2ed0>
Gribouillis 1,391 Programming Explorer Team Colleague

Sorry, but xrange was introduced in python when the iteration protocol was defined. The purpose of xrange is to yield numbers from start to stop without building explicitly a list. This was considered an improvement over range (which goes back to the very early versions of python). The fact that xrange is a type is an implementation detail: the generator must store at least an integer to yield the next value.

Gribouillis 1,391 Programming Explorer Team Colleague

It's not exactly true. xrange() is a builtin function in python 2 which returns an iterator instead of a list (range() returns a list). In python 3, range() returns an iterator, so python 3's range is python 2's xrange. In python 2, use xrange rather than range, because it's faster.

Also Garrett85, when you don't know what a builtin symbol does, go to this page http://docs.python.org/, and write the symbol in the box 'Quick Search' on the left. It's very efficient.

Gribouillis 1,391 Programming Explorer Team Colleague

Use a third dict

D = {'fstn':'Tim','lstn':'Parker','mdl':'W','dob':'19801201'}
remap = {'fstn':'FIRST_NAME','lstn':'LAST_NAME','mdl':'MIDDLE_NAME','dob':'BIRTH_DAY'}

otherD = dict((remap[key], value) for (key, value) in D.items())

print(otherD)

"""my output -->
{'BIRTH_DAY': '19801201', 'FIRST_NAME': 'Tim', 'LAST_NAME': 'Parker', 'MIDDLE_NAME': 'W'}
"""
Gribouillis 1,391 Programming Explorer Team Colleague

I ran Clone Digger on your code (easy_install clonedigger, see here http://clonedigger.sourceforge.net/). It took a while to run but it found 3023 duplicates in your code, and it says that 97 % of your lines are duplicates. See the result in the attached file

Gribouillis 1,391 Programming Explorer Team Colleague

Here is a source of inspiration and links http://en.wikipedia.org/wiki/Duplicate_code

Gribouillis 1,391 Programming Explorer Team Colleague

I don't think you can translate C++ into python if you don't understand C++. Your program does not seem too difficult to translate for someone who knows both C++ and python. The good way to translate is to understand precisely what the C++ code does and to achieve the same effect in python. Note that the C++ code uses different low level types, for example uint32_t uint16_t int16_t uint uchar int. In python, there is only one integer type. The effect of the code on these low level types must be examined attentively for code translation.

As far as I know, there is no automated tool to translate C++ in python, because the semantics of C++ code is too difficult.

So, learn C++, or find an expert to translate the code for you.

Gribouillis 1,391 Programming Explorer Team Colleague

This program is 3000 lines long. It can easily be reduced to 500 lines by refactoring. I think this is the first step before you add new features.

Beat_Slayer commented: Well said. Good point for programming. +1
Gribouillis 1,391 Programming Explorer Team Colleague

Write a program which uses matplotlib to trace a function like sqrt(abs(sin(x ** 2))). (See http://matplotlib.sourceforge.net/gallery.html).