1+ from __future__ import annotations
2+
13import inspect
4+ from typing import Any , Dict , Tuple
5+
26
3- # 1. custom_power: lambda function with positional-only x
47custom_power = lambda x = 0 , / , e = 1 : x ** e
58
6- # 2. custom_equation: positional-only, positional-or-keyword, and keyword-only params
9+
710def custom_equation (x : int = 0 , y : int = 0 , / , a : int = 1 , b : int = 1 , * , c : int = 1 ) -> float :
8- """
9- Calculates (x**a + y**b) / c with specific parameter constraints.
10- :param x: Base 1, positional-only
11- :param y: Base 2, positional-only
12- :param a: Exponent 1, positional-or-keyword
13- :param b: Exponent 2, positional-or-keyword
14- :param c: Divisor, keyword-only
15- :returns: Result as float
16- """
17- return float ((x ** a + y ** b ) / c )
18-
19- # 3. fn_w_counter: tracks total calls and caller names
20- def fn_w_counter () -> (int , dict [str , int ]):
21- """
22- Counts the number of calls and tracks the caller (__name__).
23- """
24- if not hasattr (fn_w_counter , "calls" ):
25- fn_w_counter .calls = 0
26- fn_w_counter .callers = {}
27-
28- caller_frame = inspect .currentframe ().f_back
29- caller_name = caller_frame .f_globals .get ('__name__' , 'unknown' )
30-
31- fn_w_counter .calls += 1
32- fn_w_counter .callers [caller_name ] = fn_w_counter .callers .get (caller_name , 0 ) + 1
33-
34- return (fn_w_counter .calls , fn_w_counter .callers )
11+
12+ return (x ** a + y ** b ) / c
13+
14+
15+ def fn_w_counter () -> Tuple [int , Dict [str , int ]]:
16+
17+
18+ if not hasattr (fn_w_counter , "_total" ):
19+ fn_w_counter ._total = 0 # type: ignore[attr-defined]
20+ if not hasattr (fn_w_counter , "_by_caller" ):
21+ fn_w_counter ._by_caller = {} # type: ignore[attr-defined]
22+
23+
24+ frame = inspect .currentframe ()
25+ caller_frame = frame .f_back if frame is not None else None
26+ caller_name = "<unknown>"
27+ if caller_frame is not None :
28+ caller_name = str (caller_frame .f_globals .get ("__name__" , "<unknown>" ))
29+
30+
31+ fn_w_counter ._total += 1 # type: ignore[attr-defined]
32+ by_caller : Dict [str , int ] = fn_w_counter ._by_caller # type: ignore[attr-defined]
33+ by_caller [caller_name ] = by_caller .get (caller_name , 0 ) + 1
34+
35+
36+ return int (fn_w_counter ._total ), dict (by_caller ) # type: ignore[attr-defined]
0 commit comments