[issue16468] argparse only supports iterable choices

2013-06-27 Thread paul j3
Changes by paul j3 ajipa...@gmail.com: -- nosy: +paul.j3 ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue16468 ___ ___ Python-bugs-list mailing list

[issue9625] argparse: Problem with defaults for variable nargs when using choices

2013-06-26 Thread paul j3
Changes by paul j3 ajipa...@gmail.com: -- nosy: +paul.j3 ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue9625 ___ ___ Python-bugs-list mailing list

[issue14191] argparse doesn't allow optionals within positionals

2013-05-29 Thread paul j3
paul j3 added the comment: This is a refinement of the patch with Message188609. In parse_known_intermixed_args, the temporary capture of formatted usage has been put in a try/finally structure. Positionals are now 'deactivated' with action.nargs = SUPPRESS action.default = SUPPRESS

[issue9338] argparse optionals with nargs='?', '*' or '+' can't be followed by positionals

2013-05-23 Thread paul j3
paul j3 added the comment: Here's another approach to the problem, using an iterative localized search. For simple cases it produces the same thing, but in complex cases it is more robust. It is based on two ideas: - if the action in consume_optional() is being 'greedy', use slots

[issue9338] argparse optionals with nargs='?', '*' or '+' can't be followed by positionals

2013-05-23 Thread paul j3
Changes by paul j3 ajipa...@gmail.com: Removed file: http://bugs.python.org/file30349/argparse_7.py ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue9338

[issue9338] argparse optionals with nargs='?', '*' or '+' can't be followed by positionals

2013-05-23 Thread paul j3
paul j3 added the comment: Oops, I attached the wrong file. Here's the correct one. -- Added file: http://bugs.python.org/file30350/issue9338_7.patch ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue9338

[issue9338] argparse optionals with nargs='?', '*' or '+' can't be followed by positionals

2013-05-17 Thread paul j3
paul j3 added the comment: This patch implements, I think, the ideas bethard proposed. It is test patch, not intended for production. Most of work is in ArgumentParser._get_alt_length() which - generates a pattern along the lines bethard proposed - generates a string like arg_strings_pattern

[issue9338] argparse optionals with nargs='?', '*' or '+' can't be followed by positionals

2013-05-17 Thread paul j3
paul j3 added the comment: This is a test file for the patch I just submitted. It is not a formal unitttest, but uses print output as much as assert. Cases include the example bethard used, as well as ones from test_argparse.py that initially caused problems. -- Added file: http

[issue9338] argparse optionals with nargs='?', '*' or '+' can't be followed by positionals

2013-05-14 Thread paul j3
paul j3 added the comment: I need to make one correction to my last post: '-x 1 2 -w 3 4 5 6', # w:3, x:[1,2], y:4, z:[5,6] + # w:3, x:[1], y:2, z:[4,5,6] - The second solution is only possible if 'z' is not consumed when 'y' is being processed. In current

[issue14191] argparse doesn't allow optionals within positionals

2013-05-13 Thread paul j3
Changes by paul j3 ajipa...@gmail.com: Removed file: http://bugs.python.org/file29880/mixed.patch ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue14191

[issue17965] argparse does not dest.replace('-', '_') for positionals

2013-05-13 Thread paul j3
Changes by paul j3 ajipa...@gmail.com: -- title: argparse does not dest.replace('-', '_') for postionals - argparse does not dest.replace('-', '_') for positionals ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue17965

[issue9338] argparse optionals with nargs='?', '*' or '+' can't be followed by positionals

2013-05-13 Thread paul j3
paul j3 added the comment: I've played a bit the idea that barthard sketched. I don't have all the details worked out, but I believe this is what will happen: With parser = argparse.ArgumentParser() parser.add_argument('-w') parser.add_argument('-x', nargs='+') parser.add_argument('y

[issue17890] argparse: mutually exclusive groups full of suppressed args can cause AssertionErrors

2013-05-12 Thread paul j3
paul j3 added the comment: I'm following a dozen argparse issues with patches. I haven't seen much posting by argparse experts (like bethard, david.murry) since last December. -- ___ Python tracker rep...@bugs.python.org http://bugs.python.org

[issue17940] extra code in argparse.py

2013-05-12 Thread paul j3
paul j3 added the comment: I was wondering about that block of code earlier. It would be a good idea to look at what func() does, just to make sure there aren't any side effects - e.g. set maximum line length, required indention, etc. -- nosy: +paul.j3

[issue17965] argparse does not dest.replace('-', '_') for postionals

2013-05-12 Thread paul j3
New submission from paul j3: 16.4.3.11. dest For optional argument actions,... Any internal - characters will be converted to _ characters to make sure the string is a valid attribute name. In _get_optional_kwargs(), dest = dest.replace('-', '_'); but there is nothing like

[issue14046] argparse: assertion failure if optional argument has square/round brackets in metavar

2013-05-12 Thread paul j3
Changes by paul j3 ajipa...@gmail.com: -- nosy: +paul.j3 ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue14046 ___ ___ Python-bugs-list mailing list

[issue9338] argparse optionals with nargs='?', '*' or '+' can't be followed by positionals

2013-05-12 Thread paul j3
Changes by paul j3 ajipa...@gmail.com: -- nosy: +paul.j3 ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue9338 ___ ___ Python-bugs-list mailing list

[issue14191] argparse doesn't allow optionals within positionals

2013-05-10 Thread paul j3
paul j3 added the comment: 'parse_fallback_args()' function is only in the 'test_intermixed.py' file, not the patch. It should be in the 'if __name__' section of that file, along with the modified 'exit()' method, since it is part of these testing suit, not meant to be imported

[issue14191] argparse doesn't allow optionals within positionals

2013-05-10 Thread paul j3
paul j3 added the comment: I should note one caveat: As a consequence of setting nargs to 0 for the first 'parse_know_args' step, all positional entries in the namespace get an empty list value ([]). This is produced by 'ArgumentParser._get_values'. With the builtin action classes

[issue11354] argparse: nargs could accept range of options count

2013-05-09 Thread paul j3
paul j3 added the comment: I think this patch should build on http://bugs.python.org/issue9849, which seeks to improve the error checking for nargs. There, add_argument returns an ArgumentError if the nargs value is not a valid string, interger, or it there is mismatch between a tuple

[issue11354] argparse: nargs could accept range of options count

2013-05-09 Thread paul j3
paul j3 added the comment: This patch adds this `nargs='{m,n}'` or `nargs=(m,n)` feature. It builds on the `better nargs error message` patch in http://bugs.python.org/msg187754 It includes an argparse.rst paragraph, changes to argparse.py, and additions to test_argparse.py. The tests

[issue11354] argparse: nargs could accept range of options count

2013-05-08 Thread paul j3
paul j3 added the comment: Wouldn't it be simpler to use the re {m,n} notation to grab the appropriate number of arguments? In ArgumentParser _get_nargs_pattern we could add: +# n to m arguments, nargs is re like {n,m} +elif is_mnrep(nargs): +nargs_pattern

[issue14191] argparse doesn't allow optionals within positionals

2013-05-06 Thread paul j3
paul j3 added the comment: This is a revision of the test_intermixed.py that I submitted earlier. Now `parse_intermixed_args` acts like `parse_args', and calls `parse_known_intermixed_args`. Again it is form that can exercise the idea without modifying `argparse.py`. If the parser has

[issue14191] argparse doesn't allow optionals within positionals

2013-05-06 Thread paul j3
paul j3 added the comment: This is the formal patch corresponding to the `test_intermixed.py`. It includes changes to `argparse.rst`, plus tests in `test_argparse.py`. These tests are near the end, after those for `parse_known_args`. They are roughly equivalent to the examples

[issue17890] argparse: mutually exclusive groups full of suppressed args can cause AssertionErrors

2013-05-03 Thread paul j3
paul j3 added the comment: I see three solutions - 1) gholms' patch which removes '() ' and [] ' 2) Yogesh's patch which removes all duplicated spaces. 3) remove the 2 asserts. The first 2 do the same thing most of the time, but may differ if the user somehow inserts spaces into names

[issue17890] argparse: mutually exclusive groups full of suppressed args can cause AssertionErrors

2013-05-02 Thread paul j3
paul j3 added the comment: Looks like the text = text.strip() at the end of the set of regex (in _format_actions_usage) needs to be replaced with something that removes all excess spaces, e.g. text = _re.sub( '\s+', ' ', text ).strip() -- nosy: +paul.j3

[issue17890] argparse: mutually exclusive groups full of suppressed args can cause AssertionErrors

2013-05-02 Thread paul j3
paul j3 added the comment: In the test case: class TestMutuallyExclusiveManySuppressed even with a short 'eggs' argument, there is a difference Old usage would be: usage: PROG [-h] [--eggs EGGS] new usage: PROG [-h] [--eggs EGGS] i.e. 2 v 1 space. But extra spaces are not as dramatic

[issue16142] ArgumentParser inconsistent with parse_known_args

2013-04-29 Thread paul j3
paul j3 added the comment: Correction: The patch I gave in the last message produces: parser.parse_known_args(['-ku']) (Namespace(known=False), ['u']) It doesn't take action on the '-k', and puts 'u' in extras, not '-u'. This new patch gets it right: parser.parse_known_args

[issue16970] argparse: bad nargs value raises misleading message

2013-04-25 Thread paul j3
paul j3 added the comment: An integer nargs value is only used in one of 2 ways, range(nargs) '%s'*nargs In both a negative value acts the same as a 0. I don't think the original authors though much about 'what if the code user gives a negative value?', because nargs is counting things

[issue9849] Argparse needs better error handling for nargs

2013-04-24 Thread paul j3
paul j3 added the comment: This patch adds a value test for nargs during add_argument. The core of the new test is in ArgumentParser._check_argument. add_argument() now calls ArgumentParser._check_argument(), which calls _format_args(). If it gets a TypeError, it raises a metavar ValueError

[issue9849] Argparse needs better error handling for nargs

2013-04-24 Thread paul j3
paul j3 added the comment: The attached test_nargswarn.py file tests the argparse.py patch. It tries out various nargs values, both for parsers, groups, and mutually exclusive groups. I intend to recast these to work in test_argparse.py -- Added file: http://bugs.python.org

[issue9849] Argparse needs better error handling for nargs

2013-04-24 Thread paul j3
paul j3 added the comment: This is a revision of yesterday's patch. It includes a couple of test cases that check that parser, groups, and exclusive groups all produce the error message. I also changed the metavar tuple case to return an ArgumentError, and changed test_argparse.py

[issue16970] argparse: bad nargs value raises misleading message

2013-04-24 Thread paul j3
paul j3 added the comment: http://bugs.python.org/issue9849 also deals with nargs values. However there the focus is on string values like '1', not whether an integer value can be 0 or 0. I submitted a patch that moves the nargs testing to a ArgumentParser._check_argument() method. It still

[issue9849] Argparse needs better error handling for nargs

2013-04-23 Thread paul j3
paul j3 added the comment: This nargs test using the formater applies only when the container has a help formatter. That is true for a ArgumentParser, but not for an argument_group. group = parser.add_argument_group('g') group.add_argument('bar', nargs='test') does not raise an error

[issue14191] argparse doesn't allow optionals within positionals

2013-04-23 Thread paul j3
paul j3 added the comment: Yes, http://bugs.python.org/msg166175 does use 'parse_args' in the second call. But I think things would be more flexible if we had a second function: def parse_???(self, args=None, namespace=None): args, argv = self.parse_intermixed_args(args, namespace

[issue14191] argparse doesn't allow optionals within positionals

2013-04-22 Thread paul j3
paul j3 added the comment: The attached file has a 'parse_intermixed_args()' that has the same API as 'parse_known_args()'. It follows the two parse step model args, remaining_args = optionals.parse_known_args() args, extras = positionals.parse_known_args(remaining_args, args) except

[issue14364] Argparse incorrectly handles '--'

2013-04-19 Thread paul j3
paul j3 added the comment: The patch that I recently submitted for http://bugs.python.org/issue13922 appears to solve this issue. It only removes the '--' that marked the end of options. With: parser = argparse.ArgumentParser() parser.add_argument('-f','--foo') print(parser.parse_args

[issue17204] argparser's subparsers.add_parser() should accept an ArgumentParser

2013-04-18 Thread paul j3
paul j3 added the comment: The 'subparsers' object has a _parser_class attribute that is normally set to the class of the parent parser. In the attached file I create a class CustomParser(argparse.ArgumentParser) that makes a parser instance which copies all of the attributes

[issue14191] argparse doesn't allow optionals within positionals

2013-04-18 Thread paul j3
paul j3 added the comment: Glenn Take a look at http://bugs.python.org/issue15427 I took a stab at changing the documentation, including recommending parse_known_args when porting optparse uses. -- ___ Python tracker rep...@bugs.python.org http

[issue14364] Argparse incorrectly handles '--'

2013-04-18 Thread paul j3
Changes by paul j3 ajipa...@gmail.com: -- nosy: +paul.j3 ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue14364 ___ ___ Python-bugs-list mailing list

[issue16308] Undocumented (?) behaviour change in argparse from 3.2.3 to 3.3.0

2013-04-18 Thread paul j3
paul j3 added the comment: I submitted a patch to http://bugs.python.org/issue9253 The reason why subparser became optional in the latest release is that a old test for missing positionals was phased out, and new one added. Subparsers have always had a default 'required=False', but the old

[issue16878] argparse: positional args with nargs='*' defaults to []

2013-04-17 Thread paul j3
paul j3 added the comment: In this example: p.add_argument('--foo', nargs='*', default=None) p.parse_args([]) Namespace(foo=None) p.parse_args(['--foo']) Namespace(foo=[]) 'p.parse_args([])' just assigns the default to 'foo' in the Namespace. p.parse_args(['--foo

[issue17050] argparse.REMAINDER doesn't work as first argument

2013-04-17 Thread paul j3
paul j3 added the comment: The problem isn't with REMAINDER, but with the distinction between optionals and arguments. If you change '--def' to 'def', the parse should work: p = ArgumentParser(prog='test.py') p.add_argument('remainder', nargs=argparse.REMAINDER) p.parse_args(['def

[issue17050] argparse.REMAINDER doesn't work as first argument

2013-04-17 Thread paul j3
paul j3 added the comment: Here's a way of passing an optional-like argument to a subparser: parser = argparse.ArgumentParser() subparsers = parser.add_subparsers(dest='cmd') sub1 = subparsers.add_parser('cmd') sub1.add_argument('foo',nargs='*') args = parser.parse_args('cmd

[issue14174] argparse.REMAINDER fails to parse remainder correctly

2013-04-17 Thread paul j3
paul j3 added the comment: An alternative to Jason's example: parser = argparse.ArgumentParser() parser.add_argument('app') parser.add_argument('--config') parser.add_argument('app_args', nargs=argparse.REMAINDER) args = parser.parse_args(['--config', 'bar', 'app']) print vars(args

[issue14174] argparse.REMAINDER fails to parse remainder correctly

2013-04-17 Thread paul j3
paul j3 added the comment: By the way, parser.parse_args() uses parse_known_arg(). parse_known_args returns a Namespace and a list of unknown arguments. If that list is empty, parse_args returns the Namespace. If the list is not empty, parse_args raises an error. So parse_known_args does

[issue16142] ArgumentParser inconsistent with parse_known_args

2013-04-17 Thread paul j3
paul j3 added the comment: parser = argparse.ArgumentParser() parser.add_argument('-k','--known',action='store_true') print(parser.parse_known_args(['-k','-u'])) print(parser.parse_known_args(['-ku'])) print(parser.parse_known_args(['-uk'])) I think you want these 3 cases

[issue14191] argparse doesn't allow optionals within positionals

2013-04-16 Thread paul j3
paul j3 added the comment: This patch permits the mixing of optionals with positionals, with the caveat that a particular positional cannot be split up. If: parser = ArgumentParser() parser.add_argument('-f','--foo') parser.add_argument('cmd') parser.add_argument('rest', nargs

[issue9849] Argparse needs better error handling for nargs

2013-04-16 Thread paul j3
paul j3 added the comment: It does shift the error from parse_args to add_argument, but the message 'ValueError: length of metavar tuple does not match nargs', indicates that it's a side effect of checking on the tuple form of `metavar`. http://bugs.python.org/issue9348 There is still room

[issue16988] argparse: PARSER option for nargs not documented

2013-04-16 Thread paul j3
paul j3 added the comment: I've experimented with an argparse adaptation of profile.py: parser = argparse.ArgumentParser(usage=usage) parser.add_argument('-o', '--outfile', dest=outfile, help=Save stats to outfile, metavar=path) parser.add_argument('-s', '--sort', dest=sort

[issue13922] argparse handling multiple -- in args improperly

2013-04-14 Thread paul j3
paul j3 added the comment: This patch removes only one '--', the one that put a '-' in the 'arg_strings_pattern'. It does this in 'consume_positionals' right before calling 'take_action'. As before it does not do this if nargs is PARSER or REMAINDER. test_argparse.py has two

[issue9253] argparse: optional subparsers

2013-04-13 Thread paul j3
paul j3 added the comment: This patch addresses both issues raised here: - throw an error when the subparser argument is missing - allow the subparser argument to be optional argparse.py: _SubParsersAction - add 'required=True' keyword. name(self) method - creates a name of the form

[issue9253] argparse: optional subparsers

2013-04-10 Thread paul j3
paul j3 added the comment: Further observations: parser.add_subparsers() accepts a 'dest' keyword arg, but not a 'required' one. Default of 'dest' is SUPPRESS, so the name does not appear in the Namespace. Changing it to something like 'command' will produce an entry, e.g. Namespace(command

[issue9253] argparse: optional subparsers

2013-04-09 Thread paul j3
paul j3 added the comment: I think this problem arises from a change made in http://bugs.python.org/issue10424 Changeset to default (i.e. development) is http://hg.python.org/cpython/rev/cab204a79e09 Near the end of _parse_known_args it removes a: if positionals: self.error(_('too

[issue13922] argparse handling multiple -- in args improperly

2013-04-06 Thread paul j3
paul j3 added the comment: I am working on an alternative solution that moves the '--' removal to the consume_positionals() method, and only does it if there is a corresponding '-' in the arg_strings_pattern. -- ___ Python tracker rep

[issue13922] argparse handling multiple -- in args improperly

2013-04-05 Thread paul j3
paul j3 added the comment: There are several problems with the patch provided in msg156315 This description: Added patch so that only the first '--' is removed by an argparse.PARSE or argparse.REMAINDER argument. should read Added patch so that only the first '--' is removed by arguments

[issue13922] argparse handling multiple -- in args improperly

2013-04-05 Thread paul j3
paul j3 added the comment: There's another 'feature' to the patch proposed here. It only deletes the first '--' in the list of strings passed to '_get_values' for a particular action. parser = argparse.ArgumentParser() parser.add_argument('foo') parser.add_argument('bar', nargs

[issue13966] Add disable_interspersed_args() to argparse.ArgumentParser

2013-04-04 Thread paul j3
paul j3 added the comment: Looking further at test_argparse.py, I should say that the behavior of multiple positionals when there is one cluster of positional argstrings is well illustrated in the tests. It's the behavior when there are multiple clusters (interspersed positionals) that can

[issue15427] Describe use of args parameter of argparse.ArgumentParser.parse_args

2013-04-03 Thread paul j3
paul j3 added the comment: This patch to argparse.rst adds the argument points to parse_args(). It also adds two points to the 'Upgrading optparse code' section, one about using 'nargs=argparse.REMAINDER', and other about 'parse_known_args()'. I'm not entirely happy with the format

[issue15427] Describe use of args parameter of argparse.ArgumentParser.parse_args

2013-04-03 Thread paul j3
paul j3 added the comment: I changed the reference to the optparse allow_interspersed_args attribute to the disable_interspersed_args() method. -- Added file: http://bugs.python.org/file29662/remainder.patch ___ Python tracker rep...@bugs.python.org

[issue13966] Add disable_interspersed_args() to argparse.ArgumentParser

2013-04-03 Thread paul j3
paul j3 added the comment: The optparse page gives a reason for disable_interspersed_args(): Use this if you have a command processor which runs another command which has options of its own and you want to make sure these options don’t get confused. For example, each command might have

[issue16399] argparse: append action with default list adds to list instead of overriding

2013-04-03 Thread paul j3
paul j3 added the comment: The test file, test_argparse.py, has a test case for this: 'class TestOptionalsActionAppendWithDefault' argument_signatures = [Sig('--baz', action='append', default=['X'])] successes = [ ('--baz a --baz b', NS(baz=['X', 'a', 'b

[issue13966] Add disable_interspersed_args() to argparse.ArgumentParser

2013-04-03 Thread paul j3
paul j3 added the comment: Oops, I was wrong about this: Argparse doesn't prohibit all interspersed positionals. You could, for example, have one or more positionals with other nargs that could be interspersed. But the REMAINDER one has to be last. parser.add_argument

[issue15427] Describe use of args parameter of argparse.ArgumentParser.parse_args

2013-04-02 Thread paul j3
paul j3 added the comment: The 'args=' parameter is the same as the first positional parameter used in most of the examples. That is normal Python behavior. 15.4.4.5. Beyond sys.argv explains this alternative way of specifying argv. Still 2 bullet points could be added to 15.4.4. - args

[issue14191] argparse doesn't allow optionals within positionals

2013-03-29 Thread paul j3
paul j3 added the comment: Glenn I looked at your t18a.py test case parser = ArgumentParser() parser.add_argument('--foo', dest='foo') parser.add_argument('--bar', dest='bar') parser.add_argument('foz') parser.add_argument('baz', nargs='*') and parse variations on 'a b c d

[issue9334] argparse does not accept options taking arguments beginning with dash (regression from optparse)

2013-03-22 Thread paul j3
paul j3 added the comment: This patch makes two changes to argparse.py ArgumentParser._parse_optional() - accept negative scientific and complex numbers - add the args_default_to_positional parser option _negative_number_matcher only matches integers and simple floats. This is fine

[issue9334] argparse does not accept options taking arguments beginning with dash (regression from optparse)

2013-03-17 Thread paul j3
paul j3 added the comment: I think the `re.compile(r'^-.+$')` behavior could be better achieved by inserting a simple test in `_parse_optional` before the `_negative_number_matcher` test. # behave more like optparse even if the argument looks like a option

[issue9334] argparse does not accept options taking arguments beginning with dash (regression from optparse)

2013-03-14 Thread paul j3
paul j3 added the comment: If nargs=2, type=float, an argv like '1e4 -.002' works, but '1e4 -2e-3' produces the same error as discussed here. The problem is that _negative_number_matcher does not handle scientific notation. The proposed generalize matcher, r'^-.+$', would solve

[issue9334] argparse does not accept options taking arguments beginning with dash (regression from optparse)

2013-03-14 Thread paul j3
paul j3 added the comment: We need to be careful about when or where _negative_number_match is changed. We basically do: parser = argparse.ArgumentParser(...) parser._negative_number_matcher = re.compile(r'^-.+$') This changes the value for the parser itself, but not for the groups

[issue9334] argparse does not accept options taking arguments beginning with dash (regression from optparse)

2013-03-14 Thread paul j3
paul j3 added the comment: While parser._negative_number_matcher is used during parser.parse_args() to check whether an argument string is a 'negative number' (and hence whether to classify it as A or O). parser._optionals._negative_number_matcher is used during parser.add_argument

[issue17250] argparse: Issue 15906 patch; positional with nargs='*' and string default

2013-02-19 Thread paul j3
New submission from paul j3: The production argparse applies the type conversion to a string default whether it is needed or not. With the 12776 and 15906 patch, that conversion is postponed, so that it is applied only once. However, for a positional argument with nargs='*', that conversion

[issue16940] argparse 15.4.5.1. Sub-commands documentation missing indentation

2013-01-11 Thread paul j3
New submission from paul j3: Argparse 15.4.5.1. Sub-commands In the example: parser.parse_args(['--help']) usage: PROG [-h] [--foo] {a,b} ... positional arguments: {a,b} sub-command help a a help b b help optional arguments: -h, --help show this help message and exit --foo

[issue12954] Multiprocessing logging under Windows

2011-09-09 Thread paul j3
New submission from paul j3 ajipa...@gmail.com: The Windows programming guidelines for the multiprocessing module documentation should include a warning that any logging initialization should be protected by the 'if __name__' block. Otherwise you will get duplicate logging entries

<    3   4   5   6   7   8