Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #106439
| Path | csiph.com!feeder.erje.net!2.eu.feeder.erje.net!ecngs!testfeeder.ecngs.de!81.171.118.64.MISMATCH!peer04.fr7!news.highwinds-media.com!fu-berlin.de!uni-berlin.de!not-for-mail |
|---|---|
| From | "Martin A. Brown" <martin@linux-ip.net> |
| Newsgroups | comp.lang.python |
| Subject | Re: how to optimize the below code with a helper function |
| Date | Mon, 4 Apr 2016 07:07:20 -0700 |
| Lines | 160 |
| Message-ID | <mailman.17.1459779248.32530.python-list@python.org> (permalink) |
| References | <CACT3xuUQc9wFPqG1DHM0ecwKE2J8KiFKFDui=FvWBqccAGLEoA@mail.gmail.com> <alpine.LSU.2.11.1604040639570.18407@znpeba.jbaqresebt.arg> |
| Mime-Version | 1.0 |
| Content-Type | text/plain; charset=US-ASCII |
| X-Trace | news.uni-berlin.de NyDNlZhyWvuKbydmUPrbQgIAIn5p1UIjAJYgV9hI+zoQ== |
| Return-Path | <martin@linux-ip.net> |
| X-Original-To | python-list@python.org |
| Delivered-To | python-list@mail.python.org |
| X-Spam-Status | OK 0.000 |
| X-Spam-Evidence | '*H*': 1.00; '*S*': 0.00; 'args': 0.04; 'sys': 0.05; '__name__': 0.07; 'main()': 0.07; 'skip:/ 10': 0.07; 'subject:code': 0.07; 'cc:addr:python-list': 0.09; '__future__': 0.09; 'although,': 0.09; 'func': 0.09; 'logger': 0.09; 'observation': 0.09; 'testcases': 0.09; 'variables,': 0.09; 'python': 0.10; 'def': 0.13; "'__main__':": 0.16; 'arguments:': 0.16; 'd.items():': 0.16; 'dictionary,': 0.16; 'division,': 0.16; 'from:addr:martin': 0.16; 'function?': 0.16; 'guessing': 0.16; 'i.e': 0.16; 'idea:': 0.16; 'jumps': 0.16; 'luck,': 0.16; 'main():': 0.16; 'received:hsd1.or.comcast.net': 0.16; 'received:io': 0.16; 'received:or.comcast.net': 0.16; 'received:psf.io': 0.16; 'yank': 0.16; 'string': 0.17; 'helper': 0.18; 'skip:l 30': 0.18; 'test.': 0.18; 'variable': 0.18; 'all,': 0.20; 'cc:2**0': 0.20; 'cc:addr:python.org': 0.20; 'martin': 0.22; 'function,': 0.22; 'rid': 0.22; 'simpler': 0.22; 'code,': 0.23; '(or': 0.23; 'seems': 0.23; '(you': 0.23; 'this:': 0.23; 'import': 0.24; 'header:In-Reply-To:1': 0.24; 'sort': 0.25; 'testing': 0.25; 'command': 0.26; 'sense': 0.26; 'external': 0.27; 'figure': 0.27; 'error': 0.27; 'logging': 0.27; 'parameters': 0.27; 'question': 0.27; 'data,': 0.27; 'sequence': 0.27; 'received:24': 0.28; 'function': 0.28; "skip:' 10": 0.28; 'looks': 0.29; 'command- line': 0.29; 'dictionary': 0.29; "i'm": 0.30; 'code': 0.30; 'becomes': 0.30; 'call.': 0.30; 'putting': 0.30; 'guess': 0.31; 'operations': 0.31; 'probably': 0.31; 'operate': 0.32; 'though,': 0.32; 'url:python': 0.33; 'call,': 0.33; 'optimize': 0.33; 'received:comcast.net': 0.33; 'similar': 0.33; 'case,': 0.34; 'file': 0.34; 'handle': 0.34; 'skip:d 20': 0.34; 'gets': 0.35; 'could': 0.35; 'something': 0.35; 'expected': 0.35; 'but': 0.36; 'should': 0.36; 'there': 0.36; 'url:org': 0.36; 'basic': 0.36; 'cases': 0.36; 'data.': 0.36; 'keyword': 0.36; 'subject:: ': 0.37; 'done.': 0.37; 'charset:us-ascii': 0.37; 'mean': 0.38; 'skip:o 20': 0.38; 'end': 0.39; 'why': 0.39; 'test': 0.39; 'data': 0.39; 'subject:the': 0.39; 'easily': 0.39; 'well.': 0.40; 'where': 0.40; 'subject:with': 0.40; 'your': 0.60; 'received:network': 0.61; 'further': 0.62; 'more': 0.63; 'different': 0.63; 'sample': 0.63; 'times': 0.63; 'here': 0.66; 'wish': 0.71; 'greetings': 0.71; '100': 0.79; '**kw)': 0.84; '**kw):': 0.84; '>function': 0.84; 'avoid.': 0.84; 'dict()': 0.84; 'scenarios,': 0.84; 'subject:below': 0.84; 'url:tutorial': 0.91 |
| X-X-Sender | mabrown@macron.wonderfrog.net |
| In-Reply-To | <CACT3xuUQc9wFPqG1DHM0ecwKE2J8KiFKFDui=FvWBqccAGLEoA@mail.gmail.com> |
| X-BeenThere | python-list@python.org |
| X-Mailman-Version | 2.1.21 |
| Precedence | list |
| List-Id | General discussion list for the Python programming language <python-list.python.org> |
| List-Unsubscribe | <https://mail.python.org/mailman/options/python-list>, <mailto:python-list-request@python.org?subject=unsubscribe> |
| List-Archive | <http://mail.python.org/pipermail/python-list/> |
| List-Post | <mailto:python-list@python.org> |
| List-Help | <mailto:python-list-request@python.org?subject=help> |
| List-Subscribe | <https://mail.python.org/mailman/listinfo/python-list>, <mailto:python-list-request@python.org?subject=subscribe> |
| X-Mailman-Original-Message-ID | <alpine.LSU.2.11.1604040639570.18407@znpeba.jbaqresebt.arg> |
| X-Mailman-Original-References | <CACT3xuUQc9wFPqG1DHM0ecwKE2J8KiFKFDui=FvWBqccAGLEoA@mail.gmail.com> |
| X-Received-Bytes | 9505 |
| X-Received-Body-CRC | 3376190949 |
| Xref | csiph.com comp.lang.python:106439 |
Show key headers only | View raw
Greetings (again) Ganesh,
I notice that you ask about how to optimize the code, but I think
what you mean is you want simpler code that is less repetitive and
less copy/paste error-prone. Is that correct?
Below, I make a few suggestions about how to simplify, although,
there probably is further simplification that could be done.
>I am on python 2.7.10 and Linux.
Noted. I tested my answer to your question on a Python 2.7, as
well.
>I have a python function where the similar kind of pattern
>repeating 100 of times
When you have a repetitive sequence of operations (or test cases, it
looks like), you can often figure out a way to store the parameters
as data. When the parameters become data, then, the code becomes
simpler.
>Sample code snippet:
>
>test01_log = os.path.join(LOG_DIR, "test01.log")
> cls.get_baddr['test01'] = failure.run_tool(
> test01_log, object="inode", offset="18", size="4",
> optype="set")
>
>test02_log = os.path.join(LOG_DIR, "test02.log")
> cls.get_baddr['test02'] = failure.run_tool(
> test02_log, lin=lin_02, object="lin", offset="100", size="5",
> optype="set")
> ..............................................------------------------
>
>test100_log = os.path.join(LOG_DIR, "test100.log")
> cls.get_baddr['test100'] = failure.run_tool(
> test02_log, baddr=lin_02, object="baddr", offset="100", size="5",
> optype="set")
I observe that here in the failure.run_tool() call, the logfile is
test02_log. I would have expected it to be test100_log. I'm
guessing that this is exactly the sort of copy/paste error that you
wish to avoid.
>(1) Any tips how I can optimize this i.e test case, should have a helper
>function that all test cases call.
One function that jumps out very easily (to my eye) is a function to
create the logfile name from the test case name. You will see how I
do that in the sample, so that you can call the run_tool function as
you are currently calling it.
(You might consider putting the logfile name generation into the
run_tool function, though, in which case, run_tool gets even simpler
and you can get rid of my function, addLogFilename. Hopefully, that
makes sense to you....)
>(2) Also note that failure.run_tool function can have variable
>number of argments how to handle this in the helper function?
A variable number of arguments: this seems like the perfect case
for using keyword arguments!
https://docs.python.org/2/tutorial/controlflow.html#keyword-arguments
I have one additional observation about your sample code, Ganesh.
When I read this:
cls.get_baddr['test01'] = failure.run_tool(
test01_log, object="inode", offset="18", size="4",
optype="set")
I am guessing that you are calling an external program in your test.
I also notice that you have string contents in your variables, for
example, offset="18". (That's part of why I guess you are calling
an external program as part of your test.)
If you are calling an external command in 'run_tool', why not put
the exact command-line you want to execute into the test data.
This would simplify your code and makes the test more transparent,
as well.
d = dict()
d['test01'] = dict(cmd=['some_command', '--offset', '18', '--size', '4'],
optype="set", object='inode')
Then, in run_tool, something like this:
subprocess.Popen(cmd, shell=False, stderr=logfile)
But, these suggestions are all, basically, different riffs on the
same basic idea:
Where you have many testing scenarios, try to figure out a way to
store all of the test cases in data and then have the test runner
operate on the data.
Good luck,
-Martin
#! /usr/bin/python
from __future__ import absolute_import, division, print_function
import os
import sys
import logging
logging.basicConfig(stream=sys.stderr, level=logging.INFO)
logger = logging.getLogger(__name__)
LOG_DIR = '/var/log/frobnitz'
def createTestCases(LOG_DIR):
'''create a test case data dictionary with parameters'''
d = dict()
d['test01'] = dict(object="inode", offset="18", size="4", optype="set")
lin_02 = "something"
d['test02'] = dict(object="lin", lin=lin_02, offset="18", size="5",
optype="set")
d['test100'] = dict(object="baddr", baddr=lin_02, offset="100", size="5",
optype="set")
return addLogFilename(d, LOG_DIR)
def run_tool(logfile, **kw):
logger.info('%s would execute with %r', logfile, kw)
def addLogFilename(d, logdir):
'''put the logfile name into the test case data dictionary'''
for casename, args in d.items():
args['logfile'] = os.path.join(logdir, casename + '.log')
return d
def main():
testcases = createTestCases(LOG_DIR)
get_baddr = dict()
for casename, kw in testcases.items():
# -- yank the logfile name out of the dictionary, before calling func
logfile = kw.pop('logfile')
get_baddr[casename] = run_tool(logfile, **kw)
if __name__ == '__main__':
main()
# -- end of file
--
Martin A. Brown
http://linux-ip.net/
Back to comp.lang.python | Previous | Next | Find similar | Unroll thread
Re: how to optimize the below code with a helper function "Martin A. Brown" <martin@linux-ip.net> - 2016-04-04 07:07 -0700
csiph-web