Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > How to "generalize" a function?

Reply
Thread Tools

How to "generalize" a function?

 
 
=?iso-8859-1?q?Thomas_K=F6llmann?=
Guest
Posts: n/a
 
      04-24-2005
Hi, everybody!

I'm teaching myself Python, and I have no experience in programming
apart from some years of shell scripting. So, please bear with me.

These two funktions are part of an administrative script I've set
myself as a first lesson, and, as you will see, they're practically the same,
except for one variable. So I'd like to weld them together -- but I
can't find out how to.

def writeIP(ip):
""" IP schreiben """
regex = re.compile('(.*)address(.*)')
confFile = open(networkConf, 'r')
conf = confFile.readlines()
confFile.close
for line in conf:
if regex.search(line):
addressLine = line
addressLineNum = conf.index(addressLine)
address = string.split(addressLine, ' ')
address[1] = ip + "\n"
conf[addressLineNum] = string.join(address)
confFile = open(networkConf, 'w')
confFile.writelines(conf)
confFile.close

def writeMask(mask):
""" netmask schreiben """
regex = re.compile('(.*)netmask(.*)')
confFile = open(networkConf, 'r')
conf = confFile.readlines()
confFile.close
for line in conf:
if regex.search(line):
netmaskLine = line
netmaskLineNum = conf.index(netmaskLine)
netmask = string.split(netmaskLine, ' ')
netmask[1] = mask + "\n"
conf[netmaskLineNum] = string.join(netmask)
confFile = open(networkConf, 'w')
confFile.writelines(conf)
confFile.close

I feel it should be possible to use something like

def writeFile(ip,keyword):
...

but how would I construct expressions like

netmaskLineNum = conf.index(netmaskLine)

in that case (netmask being the keyword here)?


I fear this is a really silly question and I guess I've missing a very
basic concept here. But I can't figure it out alone. Any advice much
appreciated!

Mit schönem Gruß
- Thomas


--
On the day that she left
He died but it did not show
- Neil Young, The Loner
/* PGP key auf Wunsch per e-mail || PGP key sent on request */
 
Reply With Quote
 
 
 
 
Dan Sommers
Guest
Posts: n/a
 
      04-24-2005
On Sun, 24 Apr 2005 23:40:22 +0200,
Thomas Köllmann <(E-Mail Removed)> wrote:

> Hi, everybody!
> I'm teaching myself Python, and I have no experience in programming
> apart from some years of shell scripting. So, please bear with me.


> These two funktions are part of an administrative script I've set
> myself as a first lesson, and, as you will see, they're practically
> the same, except for one variable. So I'd like to weld them together
> -- but I can't find out how to.


[ two very similar functions snipped ]


> I feel it should be possible to use something like


> def writeFile(ip,keyword):
> ...


Absolutely.

> but how would I construct expressions like


> netmaskLineNum = conf.index(netmaskLine)


> in that case (netmask being the keyword here)?


netmaskLineNum and addressLineNum are just names. They may mean
something to you and to people who read your program, but they mean
nothing to Python. So just use generic names:

for line in conf:
if regex.search( line )
theLine = line
theLineNum = conf.index( theLine )

etc.

HTH,
Dan

--
Dan Sommers
<http://www.tombstonezero.net/dan/>
μ₀ × ε₀ × c² = 1
 
Reply With Quote
 
 
 
 
Alexander Schmolck
Guest
Posts: n/a
 
      04-24-2005
Thomas Köllmann <(E-Mail Removed)> writes:

> confFile.close


You want ``confFile.close()`` -- the above won't do anything [1].

'as


Footnotes:
[1] Best practice would be something like this (don't worry to much about it
-- it just ensures the file is properly closed, even if something goes
wrong):

confFile = None
try:
confFile = open(networkConf, 'w')
confFile.writelines(conf)
finally:
if confFile: confFile.close()






 
Reply With Quote
 
Michael Spencer
Guest
Posts: n/a
 
      04-24-2005
Thomas Köllmann wrote:
> Hi, everybody!
>
> I'm teaching myself Python, and I have no experience in programming
> apart from some years of shell scripting. So, please bear with me.
>
> These two funktions are part of an administrative script I've set
> myself as a first lesson, and, as you will see, they're practically the same,
> except for one variable. So I'd like to weld them together -- but I
> can't find out how to.
>
> def writeIP(ip):
> """ IP schreiben """
> regex = re.compile('(.*)address(.*)')


This is the only difference between the functions, isn't it?
So, instead of hardwiring 'address' or 'netmask' into the regexp template, you
should insert it based on an argument passed to the function. String
interpolation works well here: e.g.,
>>> '(.*)%s(.*)' % 'netmask'

'(.*)netmask(.*)'
>>>


> confFile = open(networkConf, 'r')
> conf = confFile.readlines()
> confFile.close


Note, here you presumably mean confFile.close() i.e., you must supply the parens
to call the function.


[snip]
>
> I feel it should be possible to use something like
>
> def writeFile(ip,keyword):
> ...
>


Indeed. Use keyword as the argument to the string interpolation
>>> regex = re.compile('(.*)%s(.*)' % keyword)


> but how would I construct expressions like
>
> netmaskLineNum = conf.index(netmaskLine)
>


I think these should work unchanged. But it would be easier to read if you
changed these names to be neutral to the application e.g., instead of
netmaskLine, foundLine

HTH

Michael

 
Reply With Quote
 
Scott David Daniels
Guest
Posts: n/a
 
      04-25-2005
Alexander Schmolck wrote:
> [1] Best practice would be something like this (don't worry to much about it
> -- it just ensures the file is properly closed, even if something goes
> wrong):
>
> confFile = None
> try:
> confFile = open(networkConf, 'w')
> confFile.writelines(conf)
> finally:
> if confFile: confFile.close()
>


A clearer equivalent is:
confFile = open(networkConf, 'w')
try:
confFile.writelines(conf)
finally:
confFile.close()


You did not say whether you are looking to replace all, the first,
or the last occurrence of your search target. Assuming you really
mean all lines and the first occurrence on those lines:

def replaces(source, search, replacement):
'''Replace first of search on lines with replacement'''
pat = re.compile(search)
for line in source:
yield re.sub(pat, replacement, line, 1)

And your application might go like:

input = open(networkConf, 'r')
part1 = replaces(input, 'address', 'ip')
part2 = replaces(part1, 'netmask', 'mask')
result = list(part2)
input.close()
output = open(networkConf, 'w')
try:
output.writelines(result)
finally:
output.close()


--Scott David Daniels
http://www.velocityreviews.com/forums/(E-Mail Removed)
 
Reply With Quote
 
jfj
Guest
Posts: n/a
 
      04-25-2005
Thomas Köllmann wrote:

> Hi, everybody!
>
> I'm teaching myself Python, and I have no experience in programming
> apart from some years of shell scripting. So, please bear with me.
>
> These two funktions are part of an administrative script I've set
> myself as a first lesson, and, as you will see, they're practically the same,
> except for one variable. So I'd like to weld them together -- but I
> can't find out how to.


Pass the variable as an argument probably.
But because generally you wouldn't want to recompile the regexp (this
should be done once), you could say:

# untested
def makewriter (regexp_string):
def writeFunc(ip, regex=re.compile(regexp_string)):
confFile = open(networkConf, 'r')
conf = confFile.readlines()
confFile.close
for line in conf:
if regex.search(line):
addressLine = line
addressLineNum = conf.index(addressLine)
address = string.split(addressLine, ' ')
address[1] = ip + "\n"
conf[addressLineNum] = string.join(address)
confFile = open(networkConf, 'w')
confFile.writelines(conf)
confFile.close
return writeFunc

writeIP=makewriter('(.*)address(.*)')
writeMask=makewriter('(.*)netmask(.*)')

This is rather advanced python programming though, but it shows
cool dynamic function creation features and it's never early to
get into it

jfj

 
Reply With Quote
 
=?iso-8859-1?q?Thomas_K=F6llmann?=
Guest
Posts: n/a
 
      04-28-2005
Michael Spencer <(E-Mail Removed)> writes:

> Thomas Köllmann wrote:
>> regex = re.compile('(.*)address(.*)')

>
> This is the only difference between the functions, isn't it?
> So, instead of hardwiring 'address' or 'netmask' into the regexp
> template, you should insert it based on an argument passed to the
> function. String interpolation works well here: e.g.,
> >>> '(.*)%s(.*)' % 'netmask'

> '(.*)netmask(.*)'
> >>>


Thanks, I somehow missed this (presumably very basic) feature.

>>> confFile = open(networkConf, 'r')

>> conf = confFile.readlines()
>> confFile.close

>
> Note, here you presumably mean confFile.close() i.e., you must supply
> the parens to call the function.


Yes, thanks -- to Alexander as well, who also pointed me to that!

Mit schönem Gruß
- Thomas


--
/* PGP key auf Wunsch per e-mail || PGP key sent on request */
 
Reply With Quote
 
=?iso-8859-1?q?Thomas_K=F6llmann?=
Guest
Posts: n/a
 
      04-28-2005
Dan Sommers <(E-Mail Removed)> writes:

> On Sun, 24 Apr 2005 23:40:22 +0200,
> Thomas Köllmann <(E-Mail Removed)> wrote:
>
> netmaskLineNum and addressLineNum are just names. They may mean
> something to you and to people who read your program, but they mean
> nothing to Python. So just use generic names:


Thanks. I still get easily confused when trying to "abstract" such
things, but I guess I'll get it some fine day. I appreciate you took
the time to point that out to me -- you must have found it _extremely_
obvious.

Mit schönem Gruß
- Thomas


--
I filled and lit my pipe and sat there smoking. Nobody came in, nobody
called, nothing happened, nobody cared whether I died or went to El Paso.
- Raymond Chandler, The High Window
/* PGP key auf Wunsch per e-mail || PGP key sent on request */
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM



Advertisments