Python Forum
How do I find if a function has been defined?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How do I find if a function has been defined?
#1
Some explanation of what I'm trying to do (sorry if this is too long, the tl:dr is the same as the thread subject):

I'm writing a worksheet on introductory Python for first-year university students, in the form of a Google Colaboratory notebook.

There will be one code block which the students will fill out as they work through the sheet.

The first few functions are defined for them, then they need to add further functions to do different things as they go along.

Here's what the initial code block will look like:
def student_id():
  """Edit this so that it returns your UPnnnnn number"""
  return("UP654321")

def givenname():
  """Return your Given name (first name etc.)"""
  return("Replace this with your given name")

def surname():
  """Return your Surname"""
  return("Replace this with your Surname")

def add( x, y):
  """Create an add function which accepts two parameters and returns their sum"""
To allow the students to see how they're doing as they go along, I've got another code segment which will run unittest (and HTMLTestRunner to format the output).

So initially they will get a series of failed tests: eventually all the tests will be green, and then they've completed the work sheet. One of the learning outcomes will be to learn unit testing, so it's a good thing for them to find out about.

Here are the test classes I've come up with so far (there will be many, many more than this in the future):
class Test1NameMethods(unittest.TestCase):

  def test_1_student_id(self):
    self.assertNotEqual(
        student_id(),
        "UP654321", 
        "Change the function 'student_id' so that it has your UP number, not the one originally in there"
    )

  def test_2_givenname(self):
    self.assertNotEqual(givenname(),"Replace this with your given name", "Edit the function 'givenname' so that it returns your given (christian, first) name")

  def test_3_surname(self):
    self.assertNotEqual(surname(), "Replace this with your Surname", "Edit the function 'surname' so that it returns your surname (last name, family name)")

class Test2DataMethods(unittest.TestCase):

  def test_4_dataAdd(self):
    self.assertIs(
        "add" in dir("__main__"), 
        True,
        "Create an 'add' function which takes two parameters and returns their sum"
    )
    self.assertEqual(
        add(7,17),
        24
    )
    self.assertEqual(
        add(-7,-17),
        -24
    )
  
  def test_5_dataSubtract(self):
    self.assertIs(
        "subtract" in dir("__main__"),
        True,
        "Create a 'subtract' function which takes two arguments and subtracts the second from the first (Hint: use the 'def' keyword and look at what you did in your 'add' function"
    )

    self.assertEqual(
        subtract(10, 5),
        5
    )

    self.assertEqual(
        subtract(5, 10),
        -5
    )
(I may set up the classes to abort the testing the first time it encounters a failed test, but I don't know now).

My problem: I want the students to create the functions as they go along. So I need a test which fails if "function x is not defined". And I can't get this to work.

I've got as far as testing for "string" in dir() (Doesn't work since we're inside a method so dir() just returns self) or (as you see above) "string" in dir('__main__') which just returns the builtins, not the user-defined functions. I've tried using inspect.isfunction(string) but that causes an exception unless the file has been created.

I'm sure it's a SMOP to get exactly the right syntax, but I just can''t work it out!

One solution I've thought of is to put the student work in a file and import that, but I don't really want to do this - it's for students on their first week ever at University and I don't want to trip them up by having to work with files (especially since this year due to social distancing they'll be doing this at home without me in the room to help them out). That's why I'm trying to do this in colab.

Many thanks in advance for any help you can provide. I will summarise to the forum.
Reply
#2
You could try
import sys
mod = sys.modules['__main__']
name = "spam"
self.assertTrue(hasattr(mod, name), "Define a function" + name)
If you are not sure about the module, you could do
import inspect
mod = inspect.getmodule(student_id)
Reply
#3
Perfect!

Many thanks.
Reply
#4
In fact you can simplify this as
import __main__ as mod
...
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Variable is not defined error when trying to use my custom function code fnafgamer239 4 515 Nov-23-2023, 02:53 PM
Last Post: rob101
  Printing the variable from defined function jws 7 1,165 Sep-03-2023, 03:22 PM
Last Post: deanhystad
  Getting NameError for a function that is defined JonWayn 2 1,056 Dec-11-2022, 01:53 PM
Last Post: JonWayn
Question Help with function - encryption - messages - NameError: name 'message' is not defined MrKnd94 4 2,776 Nov-11-2022, 09:03 PM
Last Post: deanhystad
  How to print the output of a defined function bshoushtarian 4 1,236 Sep-08-2022, 01:44 PM
Last Post: deanhystad
  how can a function find the name by which it is called? Skaperen 18 3,322 Aug-24-2022, 04:52 PM
Last Post: Skaperen
  User-defined function to reset variables? Mark17 3 1,590 May-25-2022, 07:22 PM
Last Post: Gribouillis
  Error in find pearson correlation function erneelgupta 1 1,810 Mar-01-2022, 03:41 PM
Last Post: stevendaprano
  pdfminer package: can't find exgtract_text function Pavel_47 7 5,168 Jan-25-2021, 03:31 PM
Last Post: Pavel_47
Sad Function defined by branches antoniogalante 1 1,822 Dec-16-2020, 11:35 PM
Last Post: deanhystad

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020