@@ -39,14 +39,26 @@ def __init__(
3939
4040 Parameters
4141 ----------
42- source : function, scalar, ndarray, string
43- The actual function. If type is function, it will be called for
44- evaluation. If type is int or float, it will be treated as a
45- constant function. If ndarray, its points will be used for
46- interpolation. An ndarray should be as [(x0, y0, z0), (x1, y1, z1),
47- (x2, y2, z2), ...] where x0 and y0 are inputs and z0 is output. If
48- string, imports file named by the string and treats it as csv.
49- The file is converted into ndarray and should not have headers.
42+ source : callable, scalar, ndarray, string, or Function
43+ The data source to be used for the function:
44+
45+ - Callable: Called for evaluation with input values. Must have the
46+ desired inputs as arguments and return a single output value.
47+ Input order is important. Example: Python functions, classes, and
48+ methods.
49+
50+ - int or float: Treated as a constant value function.
51+
52+ - ndarray: Used for interpolation. Format as [(x0, y0, z0),
53+ (x1, y1, z1), ..., (xn, yn, zn)], where 'x' and 'y' are inputs,
54+ and 'z' is the output.
55+
56+ - string: Path to a CSV file. The file is read and converted into an
57+ ndarray. The file can optionally contain a single header line.
58+
59+ - Function: Copies the source of the provided Function object,
60+ creating a new Function with adjusted inputs and outputs.
61+
5062 inputs : string, sequence of strings, optional
5163 The name of the inputs of the function. Will be used for
5264 representation and graphing (axis names). 'Scalar' is default.
@@ -74,6 +86,13 @@ def __init__(
7486 Returns
7587 -------
7688 None
89+
90+ Notes
91+ -----
92+ (I) CSV files can optionally contain a single header line. If present,
93+ the header is ignored during processing.
94+ (II) Fields in CSV files may be enclosed in double quotes. If fields are
95+ not quoted, double quotes should not appear inside them.
7796 """
7897 # Set input and output
7998 if inputs is None :
@@ -133,25 +152,42 @@ def set_outputs(self, outputs):
133152 return self
134153
135154 def set_source (self , source ):
136- """Set the source which defines the output of the function giving a
137- certain input.
155+ """Sets the data source for the function, defining how the function
156+ produces output from a given input.
138157
139158 Parameters
140159 ----------
141- source : function, scalar, ndarray, string, Function
142- The actual function. If type is function, it will be called for
143- evaluation. If type is int or float, it will be treated as a
144- constant function. If ndarray, its points will be used for
145- interpolation. An ndarray should be as [(x0, y0, z0), (x1, y1, z1),
146- (x2, y2, z2), ...] where x0 and y0 are inputs and z0 is output. If
147- string, imports file named by the string and treats it as csv.
148- The file is converted into ndarray and should not have headers.
149- If the source is a Function, its source will be copied and another
150- Function will be created following the new inputs and outputs.
160+ source : callable, scalar, ndarray, string, or Function
161+ The data source to be used for the function:
162+
163+ - Callable: Called for evaluation with input values. Must have the
164+ desired inputs as arguments and return a single output value.
165+ Input order is important. Example: Python functions, classes, and
166+ methods.
167+
168+ - int or float: Treated as a constant value function.
169+
170+ - ndarray: Used for interpolation. Format as [(x0, y0, z0),
171+ (x1, y1, z1), ..., (xn, yn, zn)], where 'x' and 'y' are inputs,
172+ and 'z' is the output.
173+
174+ - string: Path to a CSV file. The file is read and converted into an
175+ ndarray. The file can optionally contain a single header line.
176+
177+ - Function: Copies the source of the provided Function object,
178+ creating a new Function with adjusted inputs and outputs.
179+
180+ Notes
181+ -----
182+ (I) CSV files can optionally contain a single header line. If present,
183+ the header is ignored during processing.
184+ (II) Fields in CSV files may be enclosed in double quotes. If fields are
185+ not quoted, double quotes should not appear inside them.
151186
152187 Returns
153188 -------
154189 self : Function
190+ Returns the Function instance.
155191 """
156192 _ = self ._check_user_input (
157193 source ,
@@ -165,20 +201,17 @@ def set_source(self, source):
165201 source = source .get_source ()
166202 # Import CSV if source is a string or Path and convert values to ndarray
167203 if isinstance (source , (str , Path )):
168- # Read file and check for headers
169- with open (source , mode = "r" ) as f :
170- first_line = f .readline ()
171- # If headers are found...
172- if first_line [0 ] in ['"' , "'" ]:
173- # Headers available
174- first_line = first_line .replace ('"' , " " ).replace ("'" , " " )
175- first_line = first_line .split (" , " )
176- self .set_inputs (first_line [0 ])
177- self .set_outputs (first_line [1 :])
178- source = np .loadtxt (source , delimiter = "," , skiprows = 1 , dtype = float )
179- # if headers are not found
180- else :
181- source = np .loadtxt (source , delimiter = "," , dtype = float )
204+ with open (source , "r" ) as file :
205+ try :
206+ source = np .loadtxt (file , delimiter = "," , dtype = float )
207+ except ValueError :
208+ # If an error occurs, headers are present
209+ source = np .loadtxt (source , delimiter = "," , dtype = float , skiprows = 1 )
210+ except Exception as e :
211+ raise ValueError (
212+ "The source file is not a valid csv or txt file."
213+ ) from e
214+
182215 # Convert to ndarray if source is a list
183216 if isinstance (source , (list , tuple )):
184217 source = np .array (source , dtype = np .float64 )
@@ -2830,7 +2863,15 @@ def _check_user_input(
28302863 # Deal with csv or txt
28312864 if isinstance (source , (str , Path )):
28322865 # Convert to numpy array
2833- source = np .loadtxt (source , delimiter = "," , dtype = float )
2866+ try :
2867+ source = np .loadtxt (source , delimiter = "," , dtype = float )
2868+ except ValueError :
2869+ # Skip header
2870+ source = np .loadtxt (source , delimiter = "," , dtype = float , skiprows = 1 )
2871+ except Exception as e :
2872+ raise ValueError (
2873+ "The source file is not a valid csv or txt file."
2874+ ) from e
28342875
28352876 else :
28362877 # this will also trigger an error if the source is not a list of
0 commit comments