1

I have a program for enumerating the users with administrative privileges on Windows. I also want to display the number of accounts found which is stored in a variable called num_administrator. I have the following piece of code:

if num_administrators > 1:
    print("[*] {} accounts with administrative privileges found:\n".format(num_administrators))
    show_admins()
elif num_administrators == 1:
    print("[*] {} account with administrative privileges found:\n".format(num_administrators))
    show_admins()
else:
    print("[*] No accounts with administrative privileges found.\n")

If there aren't admins I would like to print [*] No accounts with administrative privileges found. If there is 1 or more admins the message to display is almost the same, the only difference is the display of account or accounts according to the number. It's only a matter of 1 letter (s). Can I achieve the conditional print just by using a unique statement or anyway in a simpler way? Is it possible to print something like:

print("[*] {} account".format(num_administrators) + if num_administrators > 1 "s" + "with administrative privileges found:\n")

Don't mind my code above, I don't know the syntax if what I'm doing makes sense, it's just to give you an idea of what I'm thinking and you can tell me if it's doable or not.

Besides I'm calling the function show_admins() 3 times (for printing the admin accounts) but actually I can call it just once at the end I guess.

8
  • 1
    Just move your indents 4 spaces backward - your elif and else never hold as they're within if. Commented Jul 10, 2016 at 20:33
  • @dmitryro If that was the case he'd get a SyntaxError. you cannot have an elif without if. Probably just a copy&paste error. Commented Jul 10, 2016 at 20:35
  • 1
    Possible duplicate of Python conditional string formatting Commented Jul 10, 2016 at 20:36
  • ngettext was designed for exactly this purpose. Commented Jul 10, 2016 at 20:36
  • You are right, the code wasn't indented well here on Stack Overflow, but it was fine on my computer. I edited the question. Can you have a look at the question again and see what I'm asking? @dmitryro Commented Jul 10, 2016 at 20:36

4 Answers 4

2

Here's a crafty one-liner I made:

"[*] {} account{} with administrative privileges found.\n".format("No" if num_administrators == 0 else str(num_administrators), "s" if num_administrators != 1 else "")

P.S. As for readability, I don't know... I maybe be wrong, but I think my eyes are bleeding

Sign up to request clarification or add additional context in comments.

2 Comments

Please never do this ;-)
it certainly doesn't adhere to PEP 8: line too long (175 > 79 characters) but I love this one-liner :)
1

If you want to go with one line solution, that's already been answered here. However, I'd recommend using if/else statements because that way, the solution is more readable:

output = "[*] "

if num_administrators > 1:
    output += "{} accounts ".format(num_administrators)
elif num_administrators == 1:
    output += "1 account "
else:
    output += "No accounts "

output += "with administrative privileges found:\n"

1 Comment

Personally I would first do the if/else first and then do the formatting via format e.g. "[*] {} with administrative privileges found:\n".format(account_string). That way it is easier to extend the message.
0

You can do something like

 if num_administrators > 1:
       print "The total number of administrators is %d"%(num_administrators)

or, if you want it to be a string:

 if num_administrators > 1:
       print "The total number of administrators is %s"%(str(num_administrators))

So here the simplest way is to use lambda:

l = lambda x:'No' if x == 0 else x
print("[*] {} accounts with adminstrative priveleges".format(l(num_admin)))

3 Comments

You are right, this is a way to avoid the problem all together. I'd still be interested in seeing a more elegant way to achieve exactly what I asked though.
Probably lambda returning you No or the number is the simplest way to do it.
I like your solution with lambda because it is concise and still readable. There is also another similar way I found using conditional statements. I'd like to take into account also the case num_admin == 1
0

I took a look at dmitryro's solution and I like the use of lambda for displaying different strings according to a condition. I also would like to take into account the case of num_admin == 1 though. I edited the code and I got this:

l = lambda x:"No accounts" if x == 0 else ("accounts" if x > 1 else "account")

Then I edited a bit also the print statement:

print("[*] {} {} with administrative privileges found".format(num_admin, l(num_admin)))

I had to add another placeholder {} for displaying the number and I added another parameter num_admin in the format() function.

Now It's almost perfect but there is still a problem:

example:

for num_admin = 1 I get: [*] 1 account with administrative privileges found

for num_admin == 2 I get: [*] 2 accounts with administrative privileges found

but for num_admin == 0 I get: [*] 0 No accounts with administrative privileges found

I would like to avoid the display of the number 0 in front of the sentence, anyway I think I'm complicating my life and it'd be still acceptable. Besides I should consider readability as an important aspect.


I took a look at On a Friday's answer again and it actually addresses this problem:

I think in fact

print("[*] {} account{} with administrative privileges found.\n".format("No" if num_administrators == 0 else str(num_administrators), "s" if num_administrators != 1 else ""))

seems a perfect one-liner, although I agree readability might be an issue. It certainly doesn't adhere to PEP 8: line too long (175 > 79 characters).

I also like this solution because it avoids using lambda and uses conditional expressions, I think it's simpler.

See here for a reference:

- Conditional expressions

- Is there an equivalent of C’s ”?:” ternary operator?

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.