Reputation: 129
Is there a way how to simplify this static methods in python? I'm looking to reduce typing of the arguments every time I need to use a function.
class Ibeam:
def __init__ (self, b1, tf1, tw, h, b2, tf2, rt, rb):
self.b1 = b1
self.tf1 = tf1
self.tw = tw
self.h = h
self.b2 = b2
self.tf2 = tf2
self.rt = rt
self.rb = rb
def area (b1, tf1, tw, h, b2, tf2, rt, rb):
dw = h - tf1 - tf2
area = b1*tf1+tw*dw+b2*tf2+2*circularspandrel.area(rt)+2*circularspandrel.area(rb)
return area
def distToOriginZ (b1, tf1, tw, h, b2, tf2, rt, rb):
dw = h - tf1 - tf2
Dist = collections.namedtuple('Dist', 'ytf1 yw ytf2')
dist = Dist(ytf1 = h - rectangle.centroid(b1,tf1).ez, yw = rectangle.centroid(tw,dw).ez + tf2, ytf2 = rectangle.centroid(b2,tf2))
return dist
def areaMoment (b1, tf1, tw, h, b2, tf2, rt, rb):
dw = h - tf1 - tf2
sum = (rectangle.area(b1, tf1)*Ibeam.distToOriginZ(b1, tf1, tw, h, b2, tf2, rt, rb).ytf1) + (rectangle.area(tw, dw)*Ibeam.distToOriginZ(b1, tf1, tw, h, b2, tf2, rt, rb).yw) + (rectangle.area(b2,tf2)*Ibeam.distToOriginZ(b1, tf1, tw, h, b2, tf2, rt, rb).ytf2)
return sum
def centroidZ (b1, tf1, tw, h, b2, tf2, rt, rb):
ez = Ibeam.areaMoment (b1, tf1, tw, h, b2, tf2, rt, rb)/Ibeam.area(b1, tf1, tw, h, b2, tf2, rt, rb)
return ez
Upvotes: 0
Views: 59
Reputation: 2526
I'm not sure if it's what you are looking for:
But for me it looks like you want to have a class and use the functions in it.
class Ibeam:
def __init__ (self, b1, tf1, tw, h, b2, tf2, rt, rb):
self.b1 = b1
self.tf1 = tf1
self.tw = tw
self.h = h
self.b2 = b2
self.tf2 = tf2
self.rt = rt
self.rb = rb
def area (self):
dw = self.h - self.tf1 - self.tf2
area = self.b1*self.tf1+self.tw*dw+self.b2*self.tf2+2*circularspandrel.area(self.rt)+2*circularspandrel.area(self.rb)
return area
def distToOriginZ (self):
dw = self.h - self.tf1 - self.tf2
Dist = collections.namedtuple('Dist', 'ytf1 yw ytf2')
dist = Dist(ytf1 =self. h - rectangle.centroid(self.b1,self.tf1).ez, yw = rectangle.centroid(self.tw,dw).ez + self.tf2, ytf2 = rectangle.centroid(self.b2,self.tf2))
return dist
def areaMoment (self):
dw = self.h - self.tf1 - self.tf2
sum = (rectangle.area(self.b1, self.tf1)*self.distToOriginZ().ytf1) + (rectangle.area(self.tw, dw)*self.distToOriginZ()) + (rectangle.area(self.b2,self.tf2)*self.distToOriginZ().ytf2)
return sum
def centroidZ (self):
ez = self.areaMoment ()/self.area()
return ez
Now you can do the following:
beam = Ibeam(1,1,1,1,1,1,1,1)
print(beam.area())
print(beam.distToOriginZ())
print(beam.areaMoment())
print(beam.centroidZ())
With this you don't have to write that many parameters and you use proper capsulation.
With this approach you create a Class Ibeam with properties. And in this approach you are even using this properties. Before you didn't use them at all. The disadvantage is you have to create a class before, if that is not what you want use the approach with default variable and declare it static.
Upvotes: 1
Reputation: 21737
When having functions with many arguments it might be useful to think about "related" arguments and group them together. For example, consider a function that calculates the distance between two points. You could write a function like the following:
def distance(x1, y1, x2, y2):
...
return distance
print(distance(1, 2, 3, 4))
In that case, the values x1, y1
and x2, y2
are both very closely related together. you could group these together. Python gives you many options, some more expressive, some less expressive.
Your code examples look very similar, and I believe you could benefit from grouping them together.
The advantages of grouping related variables together are mainly that you reduce the number of required arguments (what you ask for), but most importantly it gives you a chance to document these variables by giving them better names.
"""
Simple Tuples
"""
def distance(point_a, point_b):
x1, y1 = point_a
x2, y2 = point_b
...
return distance
print(distance((1, 2), (3, 4)))
This is a quick-win, but it is not very expressive. So you could spice this up with named-tuples (typed or untyped) or even a full-blown object. For example:
"""
Simple named tuples (very similar to tuples, but better error-messages/repr)
"""
from collections import namedtuple
Point = namedtuple('Point', 'x, y')
def distance(point_a, point_b):
x1, y1 = point_a
x2, y2 = point_b
...
return distance
print(distance(Point(1, 2), Point(3, 4)))
"""
Typed named tuples (in case you want to use typing)
"""
from typing import NamedTuple
Point = NamedTuple('Point', [
('x', float),
('y', float),
])
def distance(point_a: Point, point_b: Point) -> float:
x1, y1 = point_a
x2, y2 = point_b
...
return distance
print(distance(Point(1, 2), Point(3, 4)))
"""
Custom Object
"""
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def distance(point_a: Point, point_b: Point) -> float:
x1, y1 = point_a.x, point_a.y
x2, y2 = point_b.x, point_b.y
...
return distance
print(distance(Point(1, 2), Point(3, 4)))
Upvotes: 0
Reputation: 2215
You could use good default values if such exist.
def area(b1=None, tf1=None, tw=None, h=None, b2=None, tf2=None, rt=None, rb=None):
....
An even better solution would be to design your class in a way that it does not require so many parameters.
Upvotes: 1