0

I am trying to make my function take an name from the user which would check if the name is in a whitelist before executing a function that prints draws out information from a pre-defined list of the same name but the entered input is being processed as a string by the function instead of the name of the list. How do I get it to take in the input as the name of the list?

hydrogen = ["Hydrogen", "H", "1", "1.0"]
helium = ["Helium", "He", "2", "4.0"]

universe = ["hydrogen", "helium"]

elementname_print = "Element Name: "
elementsymbol_print = "Element Symbol: "
atomicnumber_print = "Atomic Number: "
relativeatomicmass_print = "Relative Atomic Mass: "

def printelement(element):
  print(f" \n-------------------------")
  print(elementname_print + element[0])
  print(elementsymbol_print + element[1])
  print(atomicnumber_print + element[2])
  print(relativeatomicmass_print + element[3])
  print("-------------------------")

userinput = input("-->")
if userinput in universe:
  printelement(userinput)
else:
  print("Sorry that element cannot be found.")

Result:

--> hydrogen

Element Name: h

Element Symbol: y

Atomic Number: d

Relative Atomic Mass: r

Dan
  • 3
  • 1
  • Define them using a dictionary with keys being the strings that you want the user to use and the values being the list(s). – wwii Oct 27 '18 at 04:18

3 Answers3

3

You should, rather than defining your elements in global scope as hydrogen = ..., define them inside a dictionary keyed by their name.

elements = {"hydrogen": ["Hydrogen", "H", "1", "1.0"],
            "helium": ["Helium", "He", "2", "4.0"]}

the lookup then becomes much easier.

def print_element(element_name):
    element = elements[element_name]
    # the rest as written

Note that you can clean up your code quite a bit:

elements = {"hydrogen": ["Hydrogen", "H", "1", "1.0"],
            "helium": ["Helium", "He", "2", "4.0"]}

def print_element(element_name):
    element = elements[element_name]
    name, symbol, number, mass = element

    print(f"""
----------------------
Element Name:         {name}
Element Symbol:       {symbol}
Atomic Number:        {number}
Relative Atomic Mass: {mass}
----------------------""")

userinput = input("-->")
if userinput in elements:
    print_element(userinput)
else:
    print("Sorry that element cannot be found.")

There are ways to make your chosen solution work (eval will do it, but introduce huge security risks. globals() will do it, but introduce a large performance overhead), but they're all ugly. Writing an ugly hack is objectively worse than using the right approach in the first place

Adam Smith
  • 52,157
  • 12
  • 73
  • 112
0

You can eval the string input to the corresponding variable :

printelement(eval(userinput))

Rest code remains the same.

P.S : This is a quick hack, using eval is unsafe.

Deepak Saini
  • 2,810
  • 1
  • 19
  • 26
0

Basically your need to get a list corresponding to the user input. Use globals():

  lst = globals()[userinput]

So in your example, if user types in 'hydrogen', this will give the list hydrogen. Now do your printings.

Complete example:

hydrogen = ["Hydrogen", "H", "1", "1.0"]
helium = ["Helium", "He", "2", "4.0"]
universe = ["hydrogen", "helium"]

elementname_print = "Element Name: "
elementsymbol_print = "Element Symbol: "
atomicnumber_print = "Atomic Number: "
relativeatomicmass_print = "Relative Atomic Mass: "

def printelement(element):
  print(f" \n-------------------------")
  print(elementname_print + element[0])
  print(elementsymbol_print + element[1])
  print(atomicnumber_print + element[2])
  print(relativeatomicmass_print + element[3])
  print("-------------------------")

userinput = input("-->")
if userinput in universe:
  lst = globals()[userinput]
  printelement(lst)
else:
  print("Sorry that element cannot be found.")
Austin
  • 25,759
  • 4
  • 25
  • 48