0

I have this code that receives input of a country:

flag1 = input("Enter country 1: ")
   while not worked:
      worked = True
      try:
         code1 = pycountry.countries.get(name=flag1).alpha_2
      except AttributeError:
         try:
            code1 = pycountry.countries.get(official_name=flag1).alpha_2
         except AttributeError:
            print("Invalid Input. Visit --- for list of country names.")
            flag1 = input()
            worked = False

I am planning to add two more ways of inputting a country (by 2/3-letter codes) so I'll have 2 more try-except statements. Is there an easier, simpler way to do this check, without having to nest 4 of these statements?

Daweed
  • 1,419
  • 1
  • 9
  • 24
ScndPwa
  • 19
  • 4

2 Answers2

0

Something like the following could work:

lookups = [
    lambda x: pycountry.countries.get(name=x).alpha_2,
    lambda x: pycountry.countries.get(official_name=x).alpha_2
]

flag1 = input("Enter country 1: ")

worked = False
code1 = None

while not worked:
    for lookup in lookups:
        try:
            code1 = lookup(flag1)
        except:
            continue
        
        worked = True
        break
    
    if not worked:
        print("Invalid Input. Visit --- for list of country names.")
        flag1 = input()

An alternative could be to use the fuzzy search capability of pycountry or the lookups as described here, which allow you to search without specifying which field to search in. That may or may not be appropriate for your case.

pycountry.countries.lookup('de')
<pycountry.db.Country object at 0x...>
Kemp
  • 3,467
  • 1
  • 18
  • 27
  • To match the original code, you need to break the loop if there was no exception – Tomerikoo Feb 03 '21 at 10:36
  • Correct, I've fixed that oversight – Kemp Feb 03 '21 at 11:28
  • 1
    Now, by the way, you can remove the use of `worked` by changing the last `if` block to an `else` on the `for` loop ;) – Tomerikoo Feb 03 '21 at 11:29
  • Today I learned something :) I had no idea `for` loops could have an `else` clause. Though it would then need something extra to break out of the outer loop once an input has been accepted. – Kemp Feb 03 '21 at 13:19
  • It's really neat. Here is the [official documentation](https://docs.python.org/3/tutorial/controlflow.html#break-and-continue-statements-and-else-clauses-on-loops) and here is [a SO question](https://stackoverflow.com/questions/9979970/why-does-python-use-else-after-for-and-while-loops) on the matter – Tomerikoo Feb 03 '21 at 13:21
  • You could `break` after the `else` and put a `continue` inside it... – Tomerikoo Feb 03 '21 at 13:23
0

this is what you need. no try-except included.

import pycountry
code_1 =''
while True:
  flag1 = input("Enter country 1: ")
  aux = pycountry.countries.get(name=flag1) or pycountry.countries.get(official_name=flag1)
  if aux ==None:
    print("Invalid Input. Visit --- for list of country names.")
    continue
  code1 = aux.alpha_2
  break
print(code1)