1import secret
2
3import re
4import random
5import string
6
7# I am generating the function parameters randomly to avoid
8# having magic numbers in my code
9
10RANGE_BEGIN = 1
11RANGE_END = 100000
12
13
14def is_static_method(obj_searched, function_to_check):
15 method = getattr(obj_searched, function_to_check.__name__, None)
16
17 if method:
18 return callable(method) and getattr(method, '__self__', None) is None
19
20 return False
21
22
23def generate_random_even():
24 random_number = random.randint(RANGE_BEGIN, RANGE_END)
25 if random_number % 2 == 0:
26 return random_number
27 else:
28 # if the random number is odd, add 1 to make it even
29 return random_number + 1
30
31
32def generate_random_string():
33 length = random.randint(RANGE_BEGIN, RANGE_END)
34 characters = string.ascii_letters + string.digits + string.punctuation
35 random_string = ''.join(random.choice(characters) for _ in range(length))
36 return random_string
37
38
39def check_for_conditions(function_to_check, obj_searched):
40 function_name = function_to_check.__name__
41
42 # if the function is a part of a class, create an instance
43 # of the class so that the method has 'self'
44 if type(obj_searched) == type:
45 x = obj_searched()
46 function_to_check = getattr(x, function_name, None)
47
48 # first condition - if the function can be called with an int
49 try:
50 random_even_num = generate_random_even()
51 random_odd_num = generate_random_even() + 1
52 if (function_to_check(random_even_num) == random_even_num ** 2
53 and function_to_check(random_odd_num) == 0):
54 return True
55 except Exception:
56 pass # do nothing, check the other conditions
57
58 # second condition - the function can be called without arguments
59 # and throws BaseException or TypeError with a specific message
60 try:
61 function_to_check()
62 except TypeError as data:
63 if str(data) == "Опаааааа, тука има нещо нередно.":
64 return True
65 # else, do nothing - the type error could be caused from calling the function with wrong args
66 except BaseException:
67 return True
68
69 # third condition - if the function can be called with two strings that get concatenated
70 try:
71 left_argument = generate_random_string()
72 right_argument = generate_random_string()
73 concatenated = function_to_check(left=left_argument, right=right_argument)
74 if concatenated != (left_argument + right_argument):
75 return False
76 else:
77 return True
78 except Exception:
79 pass
80
81 # fourth condition - the method is static for the class
82 return is_static_method(obj_searched, function_to_check)
83
84
85unique_functions = set() # keep track of the unique functions
86
87
88def find_all(object_to_search):
89 """Search for objects with a name containing 'clue' or 'interesting' methods"""
90
91 # filter out dunder methods since they aren't interesting anyway
92 valid_names = [name for name in dir(object_to_search) if not name.startswith("__") and not name.endswith("__")]
93
94 for name in valid_names: # iterate over attributes of the current object
95 if re.search(r".*clue.*", name): # regex match clue
96 # search the current name
97 find_all(getattr(object_to_search, name, None))
98
99 # check if the object is a function and its name is a letter or number
100 elif callable(getattr(object_to_search, name, None)) and re.search(r"^(?!_)\w$", name):
101 if (check_for_conditions(getattr(object_to_search, name, None), object_to_search)
102 and name not in unique_functions):
103 unique_functions.add(getattr(object_to_search, name, None))
104
105
106def methodify():
107 find_all(secret)
108 return tuple(unique_functions)
Timed out.
| f | 1 | import secret | f | 1 | import secret |
| n | n | 2 | |||
| 2 | import re | 3 | import re | ||
| 3 | import random | 4 | import random | ||
| 4 | import string | 5 | import string | ||
| n | 5 | import inspect | n | ||
| 6 | 6 | ||||
| 7 | # I am generating the function parameters randomly to avoid | 7 | # I am generating the function parameters randomly to avoid | ||
| 8 | # having magic numbers in my code | 8 | # having magic numbers in my code | ||
| 9 | 9 | ||||
| 10 | RANGE_BEGIN = 1 | 10 | RANGE_BEGIN = 1 | ||
| 11 | RANGE_END = 100000 | 11 | RANGE_END = 100000 | ||
| 12 | 12 | ||||
| 13 | 13 | ||||
| n | 14 | def is_static_method(class_name, method_name): | n | 14 | def is_static_method(obj_searched, function_to_check): |
| 15 | method = getattr(class_name, method_name.__name__, None) | 15 | method = getattr(obj_searched, function_to_check.__name__, None) | ||
| 16 | 16 | ||||
| 17 | if method: | 17 | if method: | ||
| n | 18 | method_obj = inspect.unwrap(method) | n | 18 | return callable(method) and getattr(method, '__self__', None) is None |
| 19 | return ( | 19 | |||
| 20 | isinstance(method_obj, staticmethod) or | ||||
| 21 | (inspect.isfunction(method_obj) and getattr(method_obj, '__self__', None) is None) | ||||
| 22 | ) | ||||
| 23 | return False | 20 | return False | ||
| 24 | 21 | ||||
| 25 | 22 | ||||
| 26 | def generate_random_even(): | 23 | def generate_random_even(): | ||
| 27 | random_number = random.randint(RANGE_BEGIN, RANGE_END) | 24 | random_number = random.randint(RANGE_BEGIN, RANGE_END) | ||
| 28 | if random_number % 2 == 0: | 25 | if random_number % 2 == 0: | ||
| 29 | return random_number | 26 | return random_number | ||
| 30 | else: | 27 | else: | ||
| 31 | # if the random number is odd, add 1 to make it even | 28 | # if the random number is odd, add 1 to make it even | ||
| 32 | return random_number + 1 | 29 | return random_number + 1 | ||
| 33 | 30 | ||||
| 34 | 31 | ||||
| 35 | def generate_random_string(): | 32 | def generate_random_string(): | ||
| 36 | length = random.randint(RANGE_BEGIN, RANGE_END) | 33 | length = random.randint(RANGE_BEGIN, RANGE_END) | ||
| 37 | characters = string.ascii_letters + string.digits + string.punctuation | 34 | characters = string.ascii_letters + string.digits + string.punctuation | ||
| 38 | random_string = ''.join(random.choice(characters) for _ in range(length)) | 35 | random_string = ''.join(random.choice(characters) for _ in range(length)) | ||
| 39 | return random_string | 36 | return random_string | ||
| 40 | 37 | ||||
| 41 | 38 | ||||
| 42 | def check_for_conditions(function_to_check, obj_searched): | 39 | def check_for_conditions(function_to_check, obj_searched): | ||
| n | n | 40 | function_name = function_to_check.__name__ | ||
| 41 | |||||
| 43 | # if the function is a part of a class, create an instance | 42 | # if the function is a part of a class, create an instance | ||
| 44 | # of the class so that the method has 'self' | 43 | # of the class so that the method has 'self' | ||
| n | 45 | function_name = function_to_check.__name__ | n | ||
| 46 | if type(obj_searched) == type: | 44 | if type(obj_searched) == type: | ||
| 47 | x = obj_searched() | 45 | x = obj_searched() | ||
| 48 | function_to_check = getattr(x, function_name, None) | 46 | function_to_check = getattr(x, function_name, None) | ||
| 49 | 47 | ||||
| 50 | # first condition - if the function can be called with an int | 48 | # first condition - if the function can be called with an int | ||
| 51 | try: | 49 | try: | ||
| 52 | random_even_num = generate_random_even() | 50 | random_even_num = generate_random_even() | ||
| 53 | random_odd_num = generate_random_even() + 1 | 51 | random_odd_num = generate_random_even() + 1 | ||
| 54 | if (function_to_check(random_even_num) == random_even_num ** 2 | 52 | if (function_to_check(random_even_num) == random_even_num ** 2 | ||
| 55 | and function_to_check(random_odd_num) == 0): | 53 | and function_to_check(random_odd_num) == 0): | ||
| 56 | return True | 54 | return True | ||
| n | 57 | except TypeError: # function was called with invalid arguments | n | 55 | except Exception: |
| 58 | pass # do nothing, check the other conditions | 56 | pass # do nothing, check the other conditions | ||
| 59 | 57 | ||||
| 60 | # second condition - the function can be called without arguments | 58 | # second condition - the function can be called without arguments | ||
| 61 | # and throws BaseException or TypeError with a specific message | 59 | # and throws BaseException or TypeError with a specific message | ||
| 62 | try: | 60 | try: | ||
| 63 | function_to_check() | 61 | function_to_check() | ||
| 64 | except TypeError as data: | 62 | except TypeError as data: | ||
| n | 65 | # the dunder __str__ is supposed to return str (even if it's overridden), but just in case :DD | n | ||
| 66 | if type(str(data)) == str and str(data) == "Опаааааа, тука има нещо нередно.": | 63 | if str(data) == "Опаааааа, тука има нещо нередно.": | ||
| 67 | return True | 64 | return True | ||
| n | 68 | else: | n | 65 | # else, do nothing - the type error could be caused from calling the function with wrong args |
| 69 | return False | ||||
| 70 | except BaseException as data: | 66 | except BaseException: | ||
| 71 | if type(str(data)) == str: | ||||
| 72 | return True | 67 | return True | ||
| 73 | 68 | ||||
| 74 | # third condition - if the function can be called with two strings that get concatenated | 69 | # third condition - if the function can be called with two strings that get concatenated | ||
| 75 | try: | 70 | try: | ||
| 76 | left_argument = generate_random_string() | 71 | left_argument = generate_random_string() | ||
| 77 | right_argument = generate_random_string() | 72 | right_argument = generate_random_string() | ||
| 78 | concatenated = function_to_check(left=left_argument, right=right_argument) | 73 | concatenated = function_to_check(left=left_argument, right=right_argument) | ||
| 79 | if concatenated != (left_argument + right_argument): | 74 | if concatenated != (left_argument + right_argument): | ||
| 80 | return False | 75 | return False | ||
| 81 | else: | 76 | else: | ||
| 82 | return True | 77 | return True | ||
| n | 83 | n | |||
| 84 | except Exception: | 78 | except Exception: | ||
| 85 | pass | 79 | pass | ||
| 86 | 80 | ||||
| 87 | # fourth condition - the method is static for the class | 81 | # fourth condition - the method is static for the class | ||
| 88 | return is_static_method(obj_searched, function_to_check) | 82 | return is_static_method(obj_searched, function_to_check) | ||
| 89 | 83 | ||||
| 90 | 84 | ||||
| n | 91 | interesting_functions = [] # since number repetitions in a faculty numbers are possible, use list and not set | n | ||
| 92 | unique_functions = set() # keep track of the unique functions | 85 | unique_functions = set() # keep track of the unique functions | ||
| 93 | 86 | ||||
| 94 | 87 | ||||
| 95 | def find_all(object_to_search): | 88 | def find_all(object_to_search): | ||
| 96 | """Search for objects with a name containing 'clue' or 'interesting' methods""" | 89 | """Search for objects with a name containing 'clue' or 'interesting' methods""" | ||
| n | n | 90 | |||
| 97 | # filter out dunder methods since they aren't interesting anyway | 91 | # filter out dunder methods since they aren't interesting anyway | ||
| 98 | valid_names = [name for name in dir(object_to_search) if not name.startswith("__") and not name.endswith("__")] | 92 | valid_names = [name for name in dir(object_to_search) if not name.startswith("__") and not name.endswith("__")] | ||
| 99 | 93 | ||||
| 100 | for name in valid_names: # iterate over attributes of the current object | 94 | for name in valid_names: # iterate over attributes of the current object | ||
| n | 101 | if re.search(r".*[Cc]lue.*", name): # regex match clue or Clue | n | 95 | if re.search(r".*clue.*", name): # regex match clue |
| 102 | # search the current name | 96 | # search the current name | ||
| 103 | find_all(getattr(object_to_search, name, None)) | 97 | find_all(getattr(object_to_search, name, None)) | ||
| n | n | 98 | |||
| 99 | # check if the object is a function and its name is a letter or number | ||||
| 104 | elif callable(getattr(object_to_search, name, None)) and re.search(r"^(?!_)\w$", name): | 100 | elif callable(getattr(object_to_search, name, None)) and re.search(r"^(?!_)\w$", name): | ||
| n | 105 | # check if the object is a function and its name is a letter or number | n | ||
| 106 | if (check_for_conditions(getattr(object_to_search, name, None), object_to_search) | 101 | if (check_for_conditions(getattr(object_to_search, name, None), object_to_search) | ||
| 107 | and name not in unique_functions): | 102 | and name not in unique_functions): | ||
| n | 108 | unique_functions.add(str(object_to_search) + str(name)) | n | 103 | unique_functions.add(getattr(object_to_search, name, None)) |
| 109 | interesting_functions.append(name) | ||||
| 110 | 104 | ||||
| 111 | 105 | ||||
| 112 | def methodify(): | 106 | def methodify(): | ||
| 113 | find_all(secret) | 107 | find_all(secret) | ||
| t | 114 | return tuple(interesting_functions) | t | 108 | return tuple(unique_functions) |
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||
| f | 1 | import secret | f | 1 | import secret |
| 2 | import re | 2 | import re | ||
| 3 | import random | 3 | import random | ||
| 4 | import string | 4 | import string | ||
| 5 | import inspect | 5 | import inspect | ||
| 6 | 6 | ||||
| 7 | # I am generating the function parameters randomly to avoid | 7 | # I am generating the function parameters randomly to avoid | ||
| 8 | # having magic numbers in my code | 8 | # having magic numbers in my code | ||
| 9 | 9 | ||||
| 10 | RANGE_BEGIN = 1 | 10 | RANGE_BEGIN = 1 | ||
| 11 | RANGE_END = 100000 | 11 | RANGE_END = 100000 | ||
| 12 | 12 | ||||
| 13 | 13 | ||||
| 14 | def is_static_method(class_name, method_name): | 14 | def is_static_method(class_name, method_name): | ||
| 15 | method = getattr(class_name, method_name.__name__, None) | 15 | method = getattr(class_name, method_name.__name__, None) | ||
| 16 | 16 | ||||
| 17 | if method: | 17 | if method: | ||
| 18 | method_obj = inspect.unwrap(method) | 18 | method_obj = inspect.unwrap(method) | ||
| 19 | return ( | 19 | return ( | ||
| 20 | isinstance(method_obj, staticmethod) or | 20 | isinstance(method_obj, staticmethod) or | ||
| 21 | (inspect.isfunction(method_obj) and getattr(method_obj, '__self__', None) is None) | 21 | (inspect.isfunction(method_obj) and getattr(method_obj, '__self__', None) is None) | ||
| 22 | ) | 22 | ) | ||
| 23 | return False | 23 | return False | ||
| 24 | 24 | ||||
| 25 | 25 | ||||
| 26 | def generate_random_even(): | 26 | def generate_random_even(): | ||
| 27 | random_number = random.randint(RANGE_BEGIN, RANGE_END) | 27 | random_number = random.randint(RANGE_BEGIN, RANGE_END) | ||
| 28 | if random_number % 2 == 0: | 28 | if random_number % 2 == 0: | ||
| 29 | return random_number | 29 | return random_number | ||
| 30 | else: | 30 | else: | ||
| 31 | # if the random number is odd, add 1 to make it even | 31 | # if the random number is odd, add 1 to make it even | ||
| 32 | return random_number + 1 | 32 | return random_number + 1 | ||
| 33 | 33 | ||||
| 34 | 34 | ||||
| 35 | def generate_random_string(): | 35 | def generate_random_string(): | ||
| 36 | length = random.randint(RANGE_BEGIN, RANGE_END) | 36 | length = random.randint(RANGE_BEGIN, RANGE_END) | ||
| 37 | characters = string.ascii_letters + string.digits + string.punctuation | 37 | characters = string.ascii_letters + string.digits + string.punctuation | ||
| 38 | random_string = ''.join(random.choice(characters) for _ in range(length)) | 38 | random_string = ''.join(random.choice(characters) for _ in range(length)) | ||
| 39 | return random_string | 39 | return random_string | ||
| 40 | 40 | ||||
| 41 | 41 | ||||
| 42 | def check_for_conditions(function_to_check, obj_searched): | 42 | def check_for_conditions(function_to_check, obj_searched): | ||
| 43 | # if the function is a part of a class, create an instance | 43 | # if the function is a part of a class, create an instance | ||
| 44 | # of the class so that the method has 'self' | 44 | # of the class so that the method has 'self' | ||
| 45 | function_name = function_to_check.__name__ | 45 | function_name = function_to_check.__name__ | ||
| 46 | if type(obj_searched) == type: | 46 | if type(obj_searched) == type: | ||
| 47 | x = obj_searched() | 47 | x = obj_searched() | ||
| 48 | function_to_check = getattr(x, function_name, None) | 48 | function_to_check = getattr(x, function_name, None) | ||
| 49 | 49 | ||||
| 50 | # first condition - if the function can be called with an int | 50 | # first condition - if the function can be called with an int | ||
| 51 | try: | 51 | try: | ||
| 52 | random_even_num = generate_random_even() | 52 | random_even_num = generate_random_even() | ||
| 53 | random_odd_num = generate_random_even() + 1 | 53 | random_odd_num = generate_random_even() + 1 | ||
| 54 | if (function_to_check(random_even_num) == random_even_num ** 2 | 54 | if (function_to_check(random_even_num) == random_even_num ** 2 | ||
| 55 | and function_to_check(random_odd_num) == 0): | 55 | and function_to_check(random_odd_num) == 0): | ||
| 56 | return True | 56 | return True | ||
| 57 | except TypeError: # function was called with invalid arguments | 57 | except TypeError: # function was called with invalid arguments | ||
| 58 | pass # do nothing, check the other conditions | 58 | pass # do nothing, check the other conditions | ||
| 59 | 59 | ||||
| 60 | # second condition - the function can be called without arguments | 60 | # second condition - the function can be called without arguments | ||
| 61 | # and throws BaseException or TypeError with a specific message | 61 | # and throws BaseException or TypeError with a specific message | ||
| 62 | try: | 62 | try: | ||
| 63 | function_to_check() | 63 | function_to_check() | ||
| 64 | except TypeError as data: | 64 | except TypeError as data: | ||
| 65 | # the dunder __str__ is supposed to return str (even if it's overridden), but just in case :DD | 65 | # the dunder __str__ is supposed to return str (even if it's overridden), but just in case :DD | ||
| 66 | if type(str(data)) == str and str(data) == "Опаааааа, тука има нещо нередно.": | 66 | if type(str(data)) == str and str(data) == "Опаааааа, тука има нещо нередно.": | ||
| 67 | return True | 67 | return True | ||
| 68 | else: | 68 | else: | ||
| 69 | return False | 69 | return False | ||
| 70 | except BaseException as data: | 70 | except BaseException as data: | ||
| 71 | if type(str(data)) == str: | 71 | if type(str(data)) == str: | ||
| 72 | return True | 72 | return True | ||
| 73 | 73 | ||||
| 74 | # third condition - if the function can be called with two strings that get concatenated | 74 | # third condition - if the function can be called with two strings that get concatenated | ||
| 75 | try: | 75 | try: | ||
| 76 | left_argument = generate_random_string() | 76 | left_argument = generate_random_string() | ||
| 77 | right_argument = generate_random_string() | 77 | right_argument = generate_random_string() | ||
| 78 | concatenated = function_to_check(left=left_argument, right=right_argument) | 78 | concatenated = function_to_check(left=left_argument, right=right_argument) | ||
| 79 | if concatenated != (left_argument + right_argument): | 79 | if concatenated != (left_argument + right_argument): | ||
| 80 | return False | 80 | return False | ||
| 81 | else: | 81 | else: | ||
| 82 | return True | 82 | return True | ||
| 83 | 83 | ||||
| 84 | except Exception: | 84 | except Exception: | ||
| 85 | pass | 85 | pass | ||
| 86 | 86 | ||||
| 87 | # fourth condition - the method is static for the class | 87 | # fourth condition - the method is static for the class | ||
| 88 | return is_static_method(obj_searched, function_to_check) | 88 | return is_static_method(obj_searched, function_to_check) | ||
| 89 | 89 | ||||
| 90 | 90 | ||||
| 91 | interesting_functions = [] # since number repetitions in a faculty numbers are possible, use list and not set | 91 | interesting_functions = [] # since number repetitions in a faculty numbers are possible, use list and not set | ||
| 92 | unique_functions = set() # keep track of the unique functions | 92 | unique_functions = set() # keep track of the unique functions | ||
| 93 | 93 | ||||
| 94 | 94 | ||||
| 95 | def find_all(object_to_search): | 95 | def find_all(object_to_search): | ||
| 96 | """Search for objects with a name containing 'clue' or 'interesting' methods""" | 96 | """Search for objects with a name containing 'clue' or 'interesting' methods""" | ||
| 97 | # filter out dunder methods since they aren't interesting anyway | 97 | # filter out dunder methods since they aren't interesting anyway | ||
| 98 | valid_names = [name for name in dir(object_to_search) if not name.startswith("__") and not name.endswith("__")] | 98 | valid_names = [name for name in dir(object_to_search) if not name.startswith("__") and not name.endswith("__")] | ||
| 99 | 99 | ||||
| 100 | for name in valid_names: # iterate over attributes of the current object | 100 | for name in valid_names: # iterate over attributes of the current object | ||
| 101 | if re.search(r".*[Cc]lue.*", name): # regex match clue or Clue | 101 | if re.search(r".*[Cc]lue.*", name): # regex match clue or Clue | ||
| 102 | # search the current name | 102 | # search the current name | ||
| 103 | find_all(getattr(object_to_search, name, None)) | 103 | find_all(getattr(object_to_search, name, None)) | ||
| 104 | elif callable(getattr(object_to_search, name, None)) and re.search(r"^(?!_)\w$", name): | 104 | elif callable(getattr(object_to_search, name, None)) and re.search(r"^(?!_)\w$", name): | ||
| 105 | # check if the object is a function and its name is a letter or number | 105 | # check if the object is a function and its name is a letter or number | ||
| 106 | if (check_for_conditions(getattr(object_to_search, name, None), object_to_search) | 106 | if (check_for_conditions(getattr(object_to_search, name, None), object_to_search) | ||
| 107 | and name not in unique_functions): | 107 | and name not in unique_functions): | ||
| 108 | unique_functions.add(str(object_to_search) + str(name)) | 108 | unique_functions.add(str(object_to_search) + str(name)) | ||
| 109 | interesting_functions.append(name) | 109 | interesting_functions.append(name) | ||
| 110 | 110 | ||||
| 111 | 111 | ||||
| 112 | def methodify(): | 112 | def methodify(): | ||
| 113 | find_all(secret) | 113 | find_all(secret) | ||
| 114 | return tuple(interesting_functions) | 114 | return tuple(interesting_functions) | ||
| t | 115 | t | |||
| 116 | |||||
| 117 | tup = methodify() | ||||
| 118 | print(tup) |
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||