This question already has answers here:
How do I put a variable’s value inside a string (interpolate it into the string)?
(9 answers)
Closed 8 months ago.
How else can I implement a function without using ' '.join(str, name). I use this to convert tuple to str. And function def get_text should look:
def get_text(name):
return "Hello " + name
Is there another way to implement that?
def bold(get_text):
def wrapped(*name):
return "<b>{}</b>".format(get_text(" ".join(map(str, name))))
return wrapped
def italic(get_text):
def wrapped(name):
return "<i>{}</i>".format(get_text(name))
return wrapped
def underline(get_text):
def wrapped(name):
return "<u>{}</u>".format(get_text(name))
return wrapped
#bold
#italic
#underline
def get_text(*name):
return "hello " + " ".join(map(str, name))
print(get_text('Hi', 'world'))
Function returns:
<b><i><u>hello Hi world</u></i></b>
First of all, you try to re-invent wheel. If you want to make html/xml etc. page from python - there are already libraries/frameworks and tutorials for this, that will suit you much better.
However, if it's just he beginning of your programming journey, string manipulation is one of first steps.... however you also have tons of tutorials for this. Python has multiple methods to format strings (best depends on usage, really)... e.g.
fstrings (https://realpython.com/python-f-strings/)
string format (https://www.w3schools.com/python/ref_string_format.asp)
strings concatenation (but you want to avoid that one)
Basically, string documentation is where you want to look (also, tutorials above will do the trick as well)
What you are attempting to use here is using decorators - you've possibly looked to tutorial about decorators instead strings (this is quite nice and easy example to learn decorators, but decorators itself are quite complex for starters and can be confusing...)
For basic idea, decorators are methods, that wraps around another methods... let's say, you want to log time before method and after it. You could do that in that methods body, but your method should only be focused on doing one thing. E.g. method add should only add not, measure time, add, then measure time. Also, this binds measuring to your method - therefore you cannot use your method without measurement. Doesn't sound too flexible, and starts to be bit messy too...
So decorator is a nice way to have your 'inner' method body clean and focused on its role, but extending it with another functionality... Wrapping method and inner method are also independent (most of cases), and can be quickly separated... Also imagine, that you want to measure time of 'a lot of' your methods, but not every - so you put that decorator only with those methods, you want.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
While I have a good amount of experience using Python, I found that sometimes it's quite difficult to determine if relevant functions and attributes should be put inside a class. More specifically, I have a function that uses the attributes of the class, and the following functions sequentially use the returned value of the previous function. For example Function 1 --> Function 2 --> Function 3 and so forth with each function returning something.
I wish to understand if it makes sense to use a class in situations like this as it is a common occurrence with me. I want to make sure that the object (sales table) is created in a way that's logical and clean.
So far I've created just a simple class with some attributes and instance methods. I'm not sure how else I can go about it. I have looked up numerous posts on Stacks, articles and many other resources. I believe I have a decent understanding the purpose of a class but less so on when it's appropriate to use it.
To be clear, I'm not asking for help on the functions themselves or their logic (although I appreciate any suggestions!). I just want to know if using a class is the way to go. I did not include any code within the functions as I don't think their logic is relevant to my question (I can add if necessary!)
class SalesTable:
def __init__(self, banner, start_year, start_month, end_year, end_month):
"""These attributes act as filters when searching for the relevant data."""
self.banner = banner
self.start_year = start_year
self.start_month = start_month
if not end_year:
self.end_year = start_year
else:
self.end_year = end_year
if not end_month:
self.end_month = start_month
else:
self.end_month = end_month
def sales_periods(self):
"""Will create a dict with a key as the year and each year will have a list of months as the value. The
stated attributes are used ONLY here as filters to determine what years and months are included"""
pass
def find_sales_period_csv(self):
"""Using the dictionary returned from the function above, will search through the relevant directories and
subdirectories to find all the paths for individual csvs where the sales data is stored as determined by the
value in the dictionary and store the paths in a list"""
pass
def csv_to_df(self):
"""Using the list returned from the function above, will take each csv path in the list and convert them into a
dataframe and store those dateframes in another list"""
pass
def combine_dfs(self):
"""Using the list return from the function above, will concatenate all dfs into a single dataframe"""
def check_data(self):
"""Maybe do some checking here to ensure all relevant data concatenated properly (i.e total row count etc.)"""
Ideally I like to return a sales table through the last function (combine_dfs) following the sequence of functions. I can accomplish this task quite easily however, I'm not sure this is the best way I should structure my script or if it logically makes sense, despite it working as I want.
Since only sales_periods actually uses the instance attributes, and it returns a dict, not another instance of SalesTable, all the other methods can be moved out of the class and defined as regular functions:
class SalesTable:
def __init__(self, banner, start_year, start_month, end_year, end_month):
...
def sales_periods(self):
# ...
return some_dict
def find_sales_period_csv(dct):
return some_list
def csv_to_df(lst):
return some_list
def combine_dfs(lst):
return some_df
def check_data(df):
pass
And you'll call them all in a chained fashion:
x = SalesTable(...)
check_data(combine_dfs(csv_to_df(find_sales_period_csv(x.sales_periods()))))
Now take a closer look at your class: you only have two methods, __init__ and sales_periods. Unless __init__ does something expensive that you don't want to repeat (and you would call sales_periods on the same instance multiple times), the entire class can be reduced to a single function that combines __init__ and the sales_period method:
def sales_periods(banner, start_year, start_month, end_year, end_month):
...
return some_dict
check_data(combine_dfs(csv_to_df(find_sales_period_csv(sales_periods(...)))))
Ideally there are two main uses for a class:
1) To prevent repetition. If you create the same object multiple times than it should be in a class.
2) To group things together. It is a lot easier to read someones code if all the related functions and attributes are grouped together. This also makes maintainability and portability easier.
It is common for methods to call each other within a class since methods should ideally not be longer than 30 lines (though different groups have different standards). If you are calling methods only from within a class than that method should be private and you should append __ (two underscores) before that method.
If a bunch of data and functions seem to live together, which is to say you typically refer to them both at the same time, then you have good reason to think you may have an object on your hands.
Another good reason is if there's a natural name for the object. Weird, I know, but it really is a useful guiding principle.
Reading up on SOLID may also give you some food for thought.
People new to OOP tend to create too many classes (I know I did in the beginning). One problem with that is code readability: when code uses a custom class, it's often necessary to read the class definition to figure out what the class is supposed to do. If the code uses built-in types only, it's usually easier to figure out. Also, the complex internal state that is a natural feature of classes often is a source of subtle bugs and makes code more difficult to reason about.
This book is quite helpful
Each of your methods above look like they relate to the class. So lets say you had defined a bunch of functions outside the class, and you were passing the same set of ten variables as arguments to each of them. That would be a sign that they should be in the class. Accessing and modifying too many variables and passing them to other functions as arguments instead of having them as class attributes which get modified inside each of the methods would be a sign that you had failed to take advantage of one of the benefits of classes. In that book, I remember a section where they went into detail about various signs that your code needs OOP.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
So a few days ago we got this exercise where we need to make a function that takes two lists as input and calculates the difference of their averages.
Sounds simple enough, but there are a few catches:
the entire thing needs to be one line long
you can absolutely NOT use ':'
They encouraged us to use 'import', 'help()' and 'dir()'.
The thing is that I know how to make it only one line long, but the no ':' is really annoying.
The way I see it, I first need to define a function (without code) then change it's 'func_code' attr.
Any ideas on how can I do it?
And how do the params fit into this?
Any answer is appreciated!!!
Edit: thanks for all the answers and the creative minds that said char(58) is the solution, it is really creative and I haven't thought of that solution but it's not allowed since you are using ':' even though not directly.
No : means you can't use lambda. That leaves higher-order functions or eval trickery.
eval('lambda a,b{}sum(a)/len(a)-sum(b)/len(b)'.format(chr(58)))
This meets the letter of the law, but violates its spirit.
Unfortunately, without a function composition function, higher-order functions don't work very well. Implementing one without : is tricky.
Here's what should be a fairly self-contained solution, using a pickled code object. I've created it in Python 3.6, and the specific bytestring is very likely to be version specific, but you can create your own version pretty easily using the expanded code below. Anyway, here's the oneliner:
f = __import__('types').FunctionType(__import__('pickle').loads(b'\x80\x03cipykernel.codeutil\ncode_ctor\nq\x00(K\x02K\x00K\x02K\x04KCC t\x00|\x00\x83\x01t\x01|\x00\x83\x01\x1b\x00t\x00|\x01\x83\x01t\x01|\x01\x83\x01\x1b\x00\x18\x00S\x00q\x01N\x85q\x02X\x03\x00\x00\x00sumq\x03X\x03\x00\x00\x00lenq\x04\x86q\x05X\x01\x00\x00\x00aq\x06X\x01\x00\x00\x00bq\x07\x86q\x08X\x1e\x00\x00\x00<ipython-input-1-384cc87bd499>q\tX\x16\x00\x00\x00difference_of_averagesq\nK\x01C\x02\x00\x01q\x0b))tq\x0cRq\r.'), globals())
Here's what I'm doing without the one-line shenanigans:
import types # replace these import statements with calls to __import__ in the oneliner
import pickle
def difference_of_averages(a, b):
return sum(a)/len(a) - sum(b)/len(b)
payload = pickle.dumps(difference_of_averages.__code__) # embed as a literal in the oneliner
f = types.FunctionType(pickle.loads(payload), globals())
Hmm, having tried this on the few different interpreters I have at hand, it looks like my pickle string includes some nonsense from the IPython interpreter I created it in. If you get errors using my string, I'd suggest just building your own (which, if it contains any junk, will at least be junk compatible with your environment).
Not using ':' is tricky because you normally use it to define the function body, like this:
def average(number_list):
return sum(number_list) / len(number_list)
However, I know of one way to define a function that doesn't require require writing a block for its body: You can assign a lambda function (or even an already-defined function) to a function you want to define, simply by using the equal sign (=). For example, if you want to create an average() function, you might write:
average = lambda number_list: sum(number_list) / len(number_list)
average might look like a variable, but you can use it as a function. It simply calls the lambda function that takes a number_list as input and returns the average value of the number_list. You can call it like this:
value = average([10, 11, 12]) # sets value to 11
Now, lambda functions can only have one line. But that's not really a problem for you, since your task requires you to only use one line.
Do you understand what to do now? Your exercise requires you to find the average of two lists, so you might consider using a lambda function that takes two inputs (instead of just one, like in the example I gave above). Also bear in mind that you need to return the difference, and if the difference should always be positive, consider using Python's abs() function somewhere in your code.
Edit: Well, gilch's response made me realize that I can't use lambda because even they use :. So apparently you can't use my advice. It's still good to know about lambda functions, though.
The fact that you are encouraged to use import makes me wonder if it's okay for you to use an already-defined function from some module to define your own function. Kind of like this:
import math; average = math.difference_of_averages
However, that depends on you being able to find a (probably standard) function that does exactly what you want. (I've briefly checked the math and numpy modules, and haven't found anything that matches yet.)
And maybe this means that you can create a module and define it anyway you like. The module is in its own world, so it's not constrained to the rules of your exercise.
Then again, maybe not.
So unless you want to "sneak-in" a : in an eval statement (as gilch suggested), like this:
average = eval('lambda number_list' + chr(58) + ' sum(number_list) / len(number_list)')
there's no way I know of off hand to avoidi using :.
This question already has an answer here:
python string module vs str methods
(1 answer)
Closed 6 years ago.
I am new to programming therefore may sound idiotic. I am learning python where I am not able to understand how few methods like upper(), split() etc work.
I mean you directly use like below:
"ABC".upper() or "abc,xyz".split(",")
Or, you can first import string and then call these methods like below:
import string
string.upper("abc")
string.split("abc,xyz", ",")
What is the difference, and how would we import string module when we can achieve the same output without importing it.
Are there similar cases exist apart from string module?
In fact, one of the paradigm you can use in Python is the Object Oriented Programming, where you modify object state through "methods" like this: myobject.mymethod().
Syntactically, it means that the first argument of the method mymethod() is in fact the object itself. But, as Python want also to deal with other paradigms (functional programming, imperative programming, and so on), there is two syntactical ways to address this method.
One is simply as I mentioned before: myobject.mymethod(), and the other one is simply to consider that the first argument is the object itself: mymethod(myobject).
More precisely, you can realize that when you define by yourself a method because you have to specify the first argument by self which is a reference to the object itself like this:
def mymethod(self):
pass
I have a function with way to much going on in it so I've decided to split it up into smaller functions and call all my block functions inside a single function. --> e.g.
def main_function(self):
time_subtraction(self)
pay_calculation(self,todays_hours)
and -->
def time_subtraction(self):
todays_hours = datetime.combine(datetime(1,1,1,0,0,0), single_object2) - datetime.combine(datetime(1,1,1,0,0,0),single_object)
return todays_hours
So what im trying to accomplish here is to make todays_hours available to my main_function. I've read lots of documentation and other resources but apparently I'm still struggling with this aspect.
EDIT--
This is not a method of the class. Its just a file where i have a lot of functions coded and i import it where needed.
If you want to pass the return value of one function to another, you need to either nest the function calls:
pay_calculation(self, time_subtraction(self))
… or store the value so you can pass it:
hours = time_subtraction(self)
pay_calculation(self, hours)
As a side note, if these are methods in a class, you should be calling them as self.time_subtraction(), self.pay_calculation(hours), etc., not time_subtraction(self), etc. And if they aren't methods in a class, maybe they should be.
Often it makes sense for a function to take a Spam instance, and for a method of Spam to send self as the first argument, in which case this is all fine. But the fact that you've defined def time_subtraction(self): implies that's not what's going on here, and you're confused about methods vs. normal functions.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Python dynamic function creation with custom names
I have written a little script to determine whether what I wanted to do is possible. It is.
My goal is to dynamically (at runtime) create functions (or methods) which have names based on a list of arbitrary size (size of the list = number of functions dynamically created).
All the functions do the same (for now), they just print their arguments.
The following code does exactly what I want, BUT, it is not clean and very brute-force. I'm trying to figure out if there is a better way to do this.
class Binder:
def __init__(self, test_cases):
""""
test_cases: a list of function/method names.
length of test_case = number of methods created.
"""
for test_case in test_cases:
#construct a code string for creating a new method using "exec"
func_str = "def "
func_str += test_case
func_str += "(*args):"
func_str += "\n\t"
func_str += "for arg in args:"
func_str += "\n\t\t"
func_str += "print arg"
func_str += "\n"
"""
For example, func_str for test_cases[0]= "func1" is simply:
def func1(*args):
for arg in args:
print arg
"""
#use exec to define the function
exec(func_str)
#add the function as a method to this class
# for test_cases[0] = "func1", this is: self.func1 = func1
set_self = "self." + test_case + " = " + test_case
exec(set_self)
if __name__ == '__main__':
#this list holds the names of the new functions to be created
test_cases = ["func1", "func2", "func3", "func4"]
b = Binder(test_cases)
#simply call each function as the instant's attributes
b.func1(1)
b.func2(1, 3, 5)
b.func4(10)
Output is:
1
1
3
5
10
As expected.
update the content of the function would not simply be a for loop printing the args, it would do something more meaningful. I get the exact result I want from the piece of code above, just wondering if there is a better way of doing it.
update I'm tying two ends of a much bigger module. One end determines what the test cases are and among other things, populates a list of the test cases' names. The other end is the functions themselves, which must have 1:1 mapping with the name of the test case. So I have the name of the test cases, I know what I want to do with each test case, I just need to create the functions that have the name of the test cases. Since the name of the test cases are determined at runtime, the function creation based on those test cases must be at runtime as well. The number of test cases is also determined at runtime.
Is there a better way to do this??
Any and all suggestions welcome.
Thanks in advance.
Mahdi
In Python this is the most reasonable approach for generic metaprogramming.
If you need just some constants in the code then however a closure may do the trick... for example:
def multiplier(k):
"Returns a function that multiplies the argument by k"
def f(x):
return x*k
return f
For arbitrary code generation Python has an ast module and you can in theory both inspect or create functions using that approach. However in Python code is hard to represent and manipulate that way so normally the approach is to just do everything at runtime instead of compiling specific functions. When you really can get an advantage you can use eval (to get a lambda) or exec. The ast module is used mostly just for inspection.
Writing code that generates code is what is called metaprogramming and Python is not very friendly to this approach.
You may have heard that C++ claims support for metaprogramming, but indeed it's only template-based metaprogramming where you can substitute types or constants into a fixed structure. You can play some tricks using "advanced metaprogramming" like the SFINAE rule but they're nothing more than trickery.
Python doesn't need templates because the language is not statically typed and you have closures (C++ is statically typed and there are no closures), but Python doesn't help with a general metaprogramming approach (i.e. writing general code that generates or manipulates code).
If you're interested in metaprogramming then the language of choice is probably Common Lisp. Writing code that writes code is not something special for Lisp and while it's of course more difficult to write a macro (a function that writes code) than a regular run-time function still with Lisp the difficulties are mostly essential (the problem is indeed harder) and not artificial because of language limitations.
There's an old joke among lispers that goes more or less like "I'm writing code that writes code that writes code that writes code that people pays me for". Metaprogramming is indeed just the first step, after that you have meta-meta-programming (writing code that writes code generators) and so on. Of course things gets harder and harder (but once again because the problem is harder, not because of arbitrarily imposed limitations...).
First of all, this is probably a really bad idea. To see why, read the comments and the other answers.
But to answer your question, this should work (although it's a hack and might have strange side effects):
from types import MethodType
def myfunc(self, *args):
for arg in args:
print arg
class Binder(object):
def __init__(self, test_cases):
for test_case in test_cases:
method = MethodType(myfunc, self, Binder)
setattr(self, test_case, method)
In this case, the reference to the function is hardcoded, but you can of course pass it as an argument too.
This is the output:
>>> b = Binder(['a', 'b'])
>>> b.a(1, 2, 3)
1
2
3
>>> b.b('a', 20, None)
a
20
None