473,881 Members | 1,602 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Bad Code (that works) help me re-write!

I have the following piece of code, taken from a bigger module, that
even as I was writing I _knew_ there were better ways of doing it, using
a parser or somesuch at least, but learning how wasn't as fun as coding
it... And yes alarm bells went off when I found myself typing eval(),
and I'm sure this is an 'unusual' use of for: else: . And I know it's
not very robust. As an ex cuse/planation, this is what happens when you
get an idea in your head and code it until it works, rather than doing
any kind of planning / designing first :)

I have a file that indicates the syntax of commands. User input is
checked against this file until it matches one of the lines in the file.
Then the indicated commands are run.

I think what I have ended up doing is writing a kind of a brute-force
parser for the file format I have defined. The trouble is, I'm sure
there are much more 'agile' and 'elegant' ways of achieveing this, and
also getting rid of eval() !

I'm posting here in the hope that it will criticised, laughed at, picked
apart and hence I shall learn a bit about python and how to do this
properly :)
The code follows, followed by the file defining the syntax of commands.

import re

def dbg(Msg,Fn):
try:
if (TRACE[Fn] or TRACE["ALL"]):
print 'DBG:'+Fn+': '+Msg
except KeyError:
pass

def processsubstitu tions(RawCmd):
DBGBN='processs ubstitutions'
infprotect=1
subhit=1
while subhit==1:
subhit=0
for sub in Substitutions:
SubCheck=RawCmd
RawCmd=re.sub(' ~'+sub,' '.join(Substitu tions[sub]),RawCmd)
if SubCheck!=RawCm d:
#dbg('Made Substitution '+sub+' to get '+RawCmd,DBGBN)
subhit=1
infprotect=infp rotect+1
if infprotect>100:
return "ERROR: Infinitely deep substitution levels
detected."
return RawCmd

#
#...processcomm and is called with a string entered by the user.
#

def processcommand( Command):
DBGBN='processc ommand'
dbg('Before Substitution: '+Command,DBGBN )
Command=process substitutions(C ommand) # if ! aliascmd then flow
is, RawCmd->subbed->executed
# is IS aliascmd
then flow is RawCmd->Subbed->aliashit->subbed->executed
dbg('After Substitution: '+Command,DBGBN )
AliasHit=0
CommandHit=0
SplitCmd=Comman d.split()
SplitLen=len(Sp litCmd)
Cmd=SplitCmd[0]
InEtcRun=0
Error=0
CommandDefs=fil e(installroot+' FatControllerCo mmands.sav','r' )
for Def in CommandDefs:
dbg("Scanning cdef ::"+Def,DBGBN )
if Def!='ENDCOMMAN DDEFS':
DefTokens=Def.s plit()
ctr=0
for Token in DefTokens:
dbg("Doing token "+Token,DBG BN)
if re.search('inpu t:',Token):
if SplitLen>ctr:
dbg("Is an input tag. ValExp=",DBGBN)

ValidateExpress ion=Token.repla ce('input:','') .replace('<<',S plitCmd[ctr]
).replace('::SP ACE::',' ')
dbg(ValidateExp ression,DBGBN)
else:
Error=1
ErrorText='Erro r: Missing parameter.'
break
if not eval(ValidateEx pression):##NOT SAFE NOT SAFE.
Need to come up with entirely new
##way to do all this
Error=1
ErrorText='Erro r: Parameter incorrect.'
break
elif re.search('crea te:',Token):

CreateExpressio n=Token.replace ('create:',''). replace('::SPAC E::',' ')
elif Token!='+*':
if ctr>=SplitLen:
Error=1
ErrorText='Erro r: Bad command.'
break
if Token!=SplitCmd[ctr]:
Error=1
ErrorText='Erro r: Bad command.'
break
ctr+=1
CommandHit=1
else: #{EndOf for Token} all tokens found for else
eval(CreateExpr ession)
break
else: #{EndOf for Def} Check aliases
for AliasName in Aliases:
if Cmd==AliasName: #then, make cmdstring alias cmd string
and re-process
AliasCmd=' '.join(Aliases[AliasName])
AliasHit=1
dbg('Made alias hit to get '+AliasCmd,DBGB N)
break
else: #FOR loop else not an alias, so try execute as last
entity command
if not CommandHit:
global LastExecutedEnt ity
if LastExecutedEnt ity!='':
#global LastExecutedEnt ity

EntityManager.e xecute(LastExec utedEntity,Spli tCmd[0:])
else:
print '\nError: Dont know which entity to use.\n'
else:
print '\nError: Bad command.\n'
if AliasHit==1:
AliasHit=0
CommandDefs.clo se()
processcommand( AliasCmd)
CommandDefs.clo se()

......now the file. First I will explain what is in it;

The 'grammar'? Or file format I have defined is as follows. The aim is
to specify the syntax of commands that are then checked against user
input until a match is found, then eval() is used to call the function
given in the file. (bad I know)

There are sveral tokens in the file, this is what they mean

Input:(some condition, possibly containing '<<') - Whatever the user
has entered in this field replaces '<<' the resulting code must eval to
True.

Create:(functio n call using SplitCmd[]) - eval is used if
user input has matched the line to make the given function call,
SplitCmd is a list of the lines values.

+* indicates the user could enter any number of any parms , these are
handled by the code executed via the create: token.

.....simple huh?
Here's the file 'FatControllerC ommands.sav' (some lines are long, turn
off wrapping):

alias input:'<<'!='' +* create:defineal ias(SplitCmd[1],SplitCmd[2:])
define entity input:not(Entit yManager.isEnti ty('<<')) input:'<<'!='' +*
create:EntityMa nager.define(Sp litCmd[2],SplitCmd[3:])
def entity input:not(Entit yManager.isEnti ty('<<')) input:'<<'!='' +*
create:EntityMa nager.define(Sp litCmd[2],SplitCmd[3:])
delete entity input:EntityMan ager.isEntity(' <<')
create:EntityMa nager.delete(Sp litCmd[2])
del entity input:EntityMan ager.isEntity(' <<')
create:EntityMa nager.delete(Sp litCmd[2])
delete alias input:isalias(' <<') create:delalias (SplitCmd[2])
del alias input:isalias(' <<') create:delalias (SplitCmd[2])
delete substitution input:issubstit ute('<<')
create:delsubst itution(SplitCm d[2])
delete sub input:issubstit ute('<<') create:delsubst itution(SplitCm d[2])
del substitution input:issubstit ute('<<')
create:delsubst itution(SplitCm d[2])
del sub input:issubstit ute('<<') create:delsubst itution(SplitCm d[2])
execute input:EntityMan ager.isEntity(' <<') input:'<<'!='' +*
create:EntityMa nager.execute(S plitCmd[1],SplitCmd[2:])
exec input:EntityMan ager.isEntity(' <<') input:'<<'!='' +*
create:EntityMa nager.execute(S plitCmd[1],SplitCmd[2:])
x input:EntityMan ager.isEntity(' <<') input:'<<'!='' +*
create:EntityMa nager.execute(S plitCmd[1],SplitCmd[2:])
exit create:sys.exit (0)
quit create:sys.exit (0)
help create:displayh elp()
load input:'<<'!='' create:load(Spl itCmd[1])
save input:'<<'==('a ll') input:not(00)
create:save(Spl itCmd[1],SplitCmd[2])
show entities create:EntityMa nager.show()
show aliases create:showalia ses()
show substitutions create:showsubs titutions()
show subs create:showsubs titutions()
show daemons create:showdaem ons()
substitute input:'<<'!=''
create:definesu bstitution(Spli tCmd[1],SplitCmd[2:])
sub input:'<<'!='' create:definesu bstitution(Spli tCmd[1],SplitCmd[2:])
trace input:'<<'!='' create:toggletr ace(SplitCmd[1])
set input:'<<'!='' input:'<<'!='' input:'<<'!='' +*
create:SetOptio n(SplitCmd[1],SplitCmd[2],'::SPACE::'.jo in(SplitCmd[3:]))
show options create:displayo pts()
define daemon input:'<<'!='' create:createda emon(SplitCmd[2])
def daemon input:'<<'!='' create:createda emon(SplitCmd[2])
define schedule input:IsDaemon( '<<') input:'<<'!='' input:'<<'!=''
input:'<<'!=''
create:schedule daemon(SplitCmd[2],SplitCmd[3],SplitCmd[4],SplitCmd[5])
define sched input:IsDaemon( '<<') input:'<<'!='' input:'<<'!=''
input:'<<'!=''
create:schedule daemon(SplitCmd[2],SplitCmd[3],SplitCmd[4],SplitCmd[5])
def schedule input:IsDaemon( '<<') input:'<<'!='' input:'<<'!=''
input:'<<'!=''
create:schedule daemon(SplitCmd[2],SplitCmd[3],SplitCmd[4],SplitCmd[5])
def sched input:IsDaemon( '<<') input:'<<'!='' input:'<<'!=''
input:'<<'!=''
create:schedule daemon(SplitCmd[2],SplitCmd[3],SplitCmd[4],SplitCmd[5])
define task input:IsDaemon( '<<') input:'<<'!='' +*
create:adddaemo ntask(SplitCmd[2],SplitCmd[3],SplitCmd[4:])
define collector input:IsDaemon( '<<') input:'<<'!='' input:'<<'!=''
input:'<<'!='' input:'<<'!='' input:'<<'!='' input:'<<'!=''
create:adddaemo ntaskcollector( SplitCmd[2],SplitCmd[3],SplitCmd[4],SplitC
md[5],SplitCmd[6],SplitCmd[7],SplitCmd[8])
subscribe entity input:IsDaemon( '<<') input:'<<'!=''
input:EntityMan ager.isEntity(' <<')
create:adddaemo ntaskentity(Spl itCmd[2],SplitCmd[3],SplitCmd[4])
subs entity input:IsDaemon( '<<') input:'<<'!=''
input:EntityMan ager.isEntity(' <<')
create:adddaemo ntaskentity(Spl itCmd[2],SplitCmd[3],SplitCmd[4])
def task input:IsDaemon( '<<') input:'<<'!='' +*
create:adddaemo ntask(SplitCmd[2],SplitCmd[3],SplitCmd[4:])
def collector input:IsDaemon( '<<') input:'<<'!='' input:'<<'!=''
input:'<<'!='' input:'<<'!='' input:'<<'!='' input:'<<'!=''
create:adddaemo ntaskcollector( SplitCmd[2],SplitCmd[3],SplitCmd[4],SplitC
md[5],SplitCmd[6],SplitCmd[7],SplitCmd[8])
def alert input:IsDaemon( '<<') input:'<<'!='' input:'<<'!=''
input:'<<'!='' input:'<<'!='' input:'<<'!=''
create:adddaemo ntaskcollectora lert(SplitCmd[2],SplitCmd[3],SplitCmd[4],S
plitCmd[5],SplitCmd[6],'::SPACE::'.jo in(SplitCmd[7:]))
define alert input:IsDaemon( '<<') input:'<<'!='' input:'<<'!=''
input:'<<'!='' input:'<<'!='' input:'<<'!=''
create:adddaemo ntaskcollectora lert(SplitCmd[2],SplitCmd[3],SplitCmd[4],S
plitCmd[5],SplitCmd[6],'::SPACE::'.jo in(SplitCmd[7:]))
delete daemon input:IsDaemon( '<<') create:removeda emon(SplitCmd[2])
del daemon input:IsDaemon( '<<') create:removeda emon(SplitCmd[2])
delete task input:IsDaemon( '<<') input:'<<'!=''
create:removeda emontask(SplitC md[2],SplitCmd[3])
del task input:IsDaemon( '<<') input:'<<'!=''
create:removeda emontask(SplitC md[2],SplitCmd[3])
update task input:IsDaemon( '<<') input:'<<'!='' input:'<<'!=''
create:updateda emontask(SplitC md[2],SplitCmd[3],SplitCmd[4:])
upd task input:IsDaemon( '<<') input:'<<'!='' input:'<<'!=''
create:updateda emontask(SplitC md[2],SplitCmd[3],SplitCmd[4:])
delete collector input:IsDaemon( '<<') input:'<<'!='' input:'<<'!=''
create:removeda emontaskcollect or(SplitCmd[2],SplitCmd[3],SplitCmd[4])
del collector input:IsDaemon( '<<') input:'<<'!='' input:'<<'!=''
create:removeda emontaskcollect or(SplitCmd[2],SplitCmd[3],SplitCmd[4])
unsubscribe entity input:IsDaemon( '<<') input:'<<'!='' input:'<<'!=''
create:removeda emontaskentity( SplitCmd[2],SplitCmd[3],SplitCmd[4])
unsub entity input:IsDaemon( '<<') input:'<<'!='' input:'<<'!=''
create:removeda emontaskentity( SplitCmd[2],SplitCmd[3],SplitCmd[4])
activate daemon input:IsDaemon( '<<') create:makedaem onlive(SplitCmd[2])
act daemon input:IsDaemon( '<<') create:makedaem onlive(SplitCmd[2])
show active daemons create:showacti vedaemons()
deactivate daemon input:IsDaemon( '<<') create:killdaem on(SplitCmd[2])
deac daemon input:IsDaemon( '<<') create:killdaem on(SplitCmd[2])
alerts create:showaler tqueue()
handle input:'<<'!='' input:'<<'!=''
create:handleal ertrange(int(Sp litCmd[1]),int(SplitCmd[2]))
addline input:'<<'!='' +*
create:appendto script(SplitCmd[1],SplitCmd[2:])
insline input:'<<'!='' input:'<<'!='' +*
create:insertto script(SplitCmd[1],SplitCmd[2],SplitCmd[3:])
delline input:'<<'!='' input:'<<'!=''
create:delfroms cript(SplitCmd[1],SplitCmd[2])
run input:isScript( '<<') +* create:runscrip t(SplitCmd[1],SplitCmd[2:])
delete script input:'<<'!='' create:delscrip t(SplitCmd[2])
del script input:'<<'!='' create:delscrip t(SplitCmd[2])
show script input:'<<'!='' create:showscri pts(SplitCmd[2])
show scripts create:showscri pts('all')
message input:'<<'!='' +* create:message( SplitCmd[1:])
msg input:'<<'!='' +* create:message( SplitCmd[1:])
ENDDCOMMANDDEFS

Thankyou for your time pythoners, any suggestions / comments are much
appreciated.

Matt.
This email is confidential and may be privileged. If you are not the intended recipient please notify the sender immediately and delete the email fromyour computer.

You should not copy the email, use it for any purpose or disclose its contents to any other person.
Please note that any views or opinions presented in this email may be personal to the author and do not necessarily represent the views or opinions ofDigica.
It is the responsibility of the recipient to check this email for the presence of viruses. Digica accepts no liability for any damage caused by any virus transmitted by this email.

UK: Phoenix House, Colliers Way, Nottingham, NG8 6AT UK
Reception Tel: + 44 (0) 115 977 1177
Support Centre: 0845 607 7070
Fax: + 44 (0) 115 977 7000
http://www.digica.com

SOUTH AFRICA: Building 3, Parc du Cap, Mispel Road, Bellville, 7535, South Africa
Tel: + 27 (0) 21 957 4900
Fax: + 27 (0) 21 948 3135
http://www.digica.com
Oct 11 '06 #1
3 1929
Matthew Warren wrote:
I have the following piece of code,
<snip>
No doubt you will get some kind soul to suggest some things, but if you
want really good
answers I think you need explain why you want this command file (as
opposed to using
say a python script itself). Are you attempting to create a simpler
syntax than Python?
A restricted set of operations?

Giles

Oct 11 '06 #2
oop. posted with wrong account, sorry for attatched disclamers in other
posts.

Oct 11 '06 #3

Matthew Warren wrote:
-----Original Message-----
From:
py************* *************** *************** @python.org
[mailto:py****** *************** *************** *******@python. o
rg] On Behalf Of Giles Brown
Sent: 11 October 2006 12:38
To: py*********@pyt hon.org
Subject: Re: Bad Code (that works) help me re-write!

Matthew Warren wrote:
I have the following piece of code,
<snip>
No doubt you will get some kind soul to suggest some things,
but if you
want really good
answers I think you need explain why you want this command file (as
opposed to using
say a python script itself). Are you attempting to create a simpler
syntax than Python?
A restricted set of operations?

The code is from a larger project called the FatController.

FatController is currently a cli based utility for administering &
monitoring devices & applications in an enterprise environment.

Users enter commands at the prompt do things such as, define a managed
entity, execute instructions against that entity, etc

The processcommand( ) function and the command file are my attempt at
implementing the 'commands' that are available to the user. Rather than
hard-code all of the syntax and commands inside the module, I wanted an
external file to maintain the definitions of the commands available to
the user. The idea is that users will be able to implement their own
'entity' modules, which FatController will import and then use to manage
devices & applications the given entty applies to. So, at the time of
writing the code thought It would be a good idea to have the command
definitions file external to the code, so and-users who write their own
modules can also extend the cammands available to Fatcontroller for
using those modules, if required.

Matt.
More info. An entity 'module' is something that creates connections to
an app/device/machine using whatever protocol, sends native commands to
that device/app/machine, and returns the result. For example, I have
written an entity of type 'TELNET' that manages anything that you can
use telnet to connect to (hence prev. post on using twisted rather than
telnetlib) . The user could enter something like the following at the
Fatcontroller prompt;

FC:define entity TELNET unixbox1 192.168.4.5 23 mylogin mypass

the user could then write something like;

FC:execute unixbox1 ps -ef | grep -c crit_process

the processcommand( ) function and the command definition file are used
to parse/analyse the user input and pass the relevant parms to the
entity module that then defines the entity for later use/managment, or
pass the given entity command to the entity for execution, and return
of the output. Fatcontroller provides other functionality for working
with entities / groups of entities, scheduling commands to be run
against entites / groups of entities and saving / extracting / alerting
against the output.
....but really, all I'm after is a learning experience, (this whole
project is what I decided to do to learn python) and I know
processcommand( ) can be written in a more elegant way and that eval()
shouldnt be there, but I have no formal acquaintance with things like
parsers and the subtleties of pythons approach etc.. So I'm hoping
through deconstructing and rebulding the code I can increase my
knowledge of python and the pythonic way to do things.

Aaanyhoo,

Ta :)

Matt.

Matt.

Oct 11 '06 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
5492
by: lawrence | last post by:
Can anyone tell me why this code works in Netscape 7.1 but not in IE??? <SCRIPT type='text/javascript'> function makeVisible(nameOfDiv) { document.getElementById(nameOfDiv).style.visibility='visible'; document.getElementById(nameOfDiv).style.height='auto'; if (nameOfDiv != 'weblogs')
2
1389
by: John | last post by:
I am having a weird error and maybe the synatax is different or something. I use a SQL Stored Proc and pass it one param and get a return to either a datareader or dataset. The code works fine for a datareader but the dataset gives me a weird error. I even tried using the same SP with the two code snippets, one works the other doesn't. tmpSQL.SQLDB.Open() tmpSQL.SQLCmd.CommandType = CommandType.StoredProcedure tmpSQL.SQLCmd.CommandText =...
2
2175
by: Enrique Bustamante | last post by:
Casting arrays that works on watch and command window but not in code. My application is casting arrays in a way it should work. To test if I was doing something invalid, I wrote a test code that has similar structure of the classes in my application. The test worked fine, the casting I want to do must work. I compared the structure of the test with the application to ensure they where similar (inheriting twice, base class implements...
2
1552
by: Raghu | last post by:
(Sorry for cross post but kinda in a hurry) I have com+ server applicaiton on machine A. The exported application proxy is installed on machine B. Both machines have windows 2003 os. Both machines are configured to be application servers. I created on machine B: 1) A vbs file 2) VB.NET assembly Both create the same component using CreateObject on machine B as shown
2
2422
by: corymac | last post by:
Hello, I've customized the panview code to accommodate what I want it to do, but I'm having a problem with it in IE. Firefox works fine. Panning the image in IE doesn't work and I think it has something to do with scrollTop, but i have no idea what to do to fix it. If I take the pan image code out of the html page and have it by itself it works.
0
1002
by: Allen | last post by:
Hi Everybody, I would appreciate it if you can give me a hand here. I want to use the two codes, below, together to do the following when the "IN" button is clicked (InBtn_Click):- 1- Create (or open) output.txt, and 2- Type the current time (hour only) in it.
4
1103
by: Grayslin | last post by:
Got some code that works in IE, when I run in FF nothing happens. If I debug the code in venkman or firebug it magically works. But if I just run it in Firefox nothing happens? any Ideas? HTML Anchor tag <a id="143066" name="143066" href="page.php" onclick="return trackclick(this.href, this.name, '143066 anchor text:page1');">Page 1</a> tracker.js thats included in the head. using: <script type="text/javascript" src="js/tracker.js">
8
1655
by: Luis Angel Fernandez Fernandez | last post by:
Hi why this code works? #include <iostream> class A { public: void foo() {std::cout << "hi" << std::endl; }; };
1
2177
by: reemamg | last post by:
Have a piece of code which works in Firefox however doesnt work in IE <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <TITLE> New Document </TITLE> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <META NAME="Author" CONTENT=""> <META NAME="Keywords" CONTENT=""> <META NAME="Description" CONTENT="">
4
1461
by: teressa | last post by:
Please Help me in this My Code is ---------------- <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="Fi._Default" %> <html> <head> <title>Member Login</title> <script type= "text/javascript" language="JavaScript">
0
9926
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9776
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10716
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10812
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9552
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
7108
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5976
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4597
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
3223
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.