Skip to content

Commit ea2ecb4

Browse files
Merge pull request #5 from upb-lea/check_type
Check user input types
2 parents 0ca6eaa + 24b44cb commit ea2ecb4

File tree

1 file changed

+101
-14
lines changed

1 file changed

+101
-14
lines changed

pysignalscope/scope.py

Lines changed: 101 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -92,21 +92,41 @@ def modify(self, channel_data_factor: Optional[float] = None, channel_data_offse
9292
:return: None
9393
:rtype: None
9494
"""
95-
if channel_label is not None:
95+
if isinstance(channel_label, str) or channel_label is None:
9696
self.channel_label = channel_label
97-
if channel_unit is not None:
97+
else:
98+
raise TypeError("channel_label must be type str or None")
99+
if isinstance(channel_unit, str) or channel_unit is None:
98100
self.channel_unit = channel_unit
99-
if channel_data_factor is not None:
101+
else:
102+
raise TypeError("channel_unit must be type str or None")
103+
if isinstance(channel_data_factor, (int, float)):
100104
self.channel_data = self.channel_data * channel_data_factor
101-
if channel_data_offset is not None:
105+
elif channel_data_factor is None:
106+
pass
107+
else:
108+
raise TypeError("channel_data_factor must be type float or None")
109+
if isinstance(channel_data_offset, (int, float)):
102110
self.channel_data = self.channel_data + channel_data_offset
103-
if channel_color is not None:
111+
elif channel_data_offset is None:
112+
pass
113+
else:
114+
raise TypeError("channel_data_offset must be type float or None")
115+
if isinstance(channel_color, str) or channel_color is None:
104116
self.channel_color = channel_color
105-
if channel_source is not None:
117+
else:
118+
raise TypeError("channel_color must be type str or None")
119+
if isinstance(channel_source, str) or channel_source is None:
106120
self.channel_source = channel_source
107-
if channel_time_shift is not None:
121+
else:
122+
raise TypeError("channel_source must be type str or None")
123+
if isinstance(channel_time_shift, (int, float)):
108124
self.channel_time = self.channel_time + channel_time_shift
109-
if channel_time_shift_rotate is not None:
125+
elif channel_time_shift is None:
126+
pass
127+
else:
128+
raise TypeError("channel_time_shift must be type float or None")
129+
if isinstance(channel_time_shift_rotate, (int, float)):
110130
# figure out current max time
111131
current_max_time = self.channel_time[-1]
112132
current_period = current_max_time - self.channel_time[0]
@@ -117,8 +137,12 @@ def modify(self, channel_data_factor: Optional[float] = None, channel_data_offse
117137
new_index = np.argsort(self.channel_time)
118138
self.channel_time = np.array(self.channel_time)[new_index]
119139
self.channel_data = np.array(self.channel_data)[new_index]
140+
elif channel_time_shift_rotate is None:
141+
pass
142+
else:
143+
raise TypeError("channel_time_shift_rotate must be type str or None")
120144

121-
if channel_time_cut_min is not None:
145+
if isinstance(channel_time_cut_min, (int, float)):
122146
index_list_to_remove = []
123147
if channel_time_cut_min < self.channel_time[0]:
124148
raise ValueError(f"channel_cut_time_min ({channel_time_cut_min}) < start of channel_time ({self.channel_time[0]}). This is not allowed!")
@@ -127,8 +151,12 @@ def modify(self, channel_data_factor: Optional[float] = None, channel_data_offse
127151
index_list_to_remove.append(count)
128152
self.channel_time = np.delete(self.channel_time, index_list_to_remove)
129153
self.channel_data = np.delete(self.channel_data, index_list_to_remove)
154+
elif channel_time_cut_min is None:
155+
pass
156+
else:
157+
raise TypeError("channel_time_cut_min must be type float or None")
130158

131-
if channel_time_cut_max is not None:
159+
if isinstance(channel_time_cut_max, (int, float)):
132160
index_list_to_remove = []
133161
if channel_time_cut_max > self.channel_time[-1]:
134162
raise ValueError(f"channel_cut_time_max ({channel_time_cut_max}) > end of channel_time ({self.channel_time[-1]}). This is not allowed!")
@@ -137,8 +165,16 @@ def modify(self, channel_data_factor: Optional[float] = None, channel_data_offse
137165
index_list_to_remove.append(count)
138166
self.channel_time = np.delete(self.channel_time, index_list_to_remove)
139167
self.channel_data = np.delete(self.channel_data, index_list_to_remove)
140-
if channel_linestyle is not None:
168+
elif channel_time_cut_max is None:
169+
pass
170+
else:
171+
raise TypeError("channel_time_cut_max must be type float or None")
172+
if isinstance(channel_linestyle, str):
141173
self.channel_linestyle = channel_linestyle
174+
elif channel_linestyle is None:
175+
pass
176+
else:
177+
raise TypeError("channel_linestyle must be type str or None")
142178

143179
def copy(self):
144180
"""Create a deepcopy of Channel."""
@@ -164,6 +200,9 @@ def from_tektronix(cls, csv_file: str) -> List['Scope']:
164200
"""
165201
channel_source = 'Tektronix scope'
166202

203+
if not isinstance(csv_file, str):
204+
raise TypeError("csv_file must be type str to show the full filepath.")
205+
167206
file: np.ndarray = np.genfromtxt(csv_file, delimiter=',', dtype=float, skip_header=15)
168207
channel_counts = file.shape[1] - 1
169208
time = file[:, 0]
@@ -199,6 +238,8 @@ def from_tektronix_mso58(*csv_files: str) -> List['Scope']:
199238

200239
tektronix_channels = []
201240
for csv_file in csv_files:
241+
if not isinstance(csv_file, str):
242+
raise TypeError("csv_file must be type str to show the full filepath.")
202243
file: np.ndarray = np.genfromtxt(csv_file, delimiter=',', dtype=float, skip_header=24)
203244
time = file[:, 0]
204245
ch1_data = file[:, 1]
@@ -226,6 +267,9 @@ def from_tektronix_mso58_multichannel(csv_file: str) -> List['Scope']:
226267
"""
227268
channel_source = 'Tektronix scope MSO58'
228269

270+
if not isinstance(csv_file, str):
271+
raise TypeError("csv_file must be type str to show the full filepath.")
272+
229273
file: np.ndarray = np.genfromtxt(csv_file, delimiter=',', dtype=float, skip_header=24)
230274
channel_counts = file.shape[1] - 1
231275
time = file[:, 0]
@@ -262,6 +306,8 @@ def from_lecroy(cls, *csv_files: str) -> List['Scope']:
262306

263307
lecroy_channel = []
264308
for csv_file in csv_files:
309+
if not isinstance(csv_file, str):
310+
raise TypeError("csv_file must be type str to show the full filepath.")
265311
file: np.ndarray = np.genfromtxt(csv_file, delimiter=',', dtype=float, skip_header=5)
266312
time = file[:, 0]
267313
ch1_data = file[:, 1]
@@ -285,6 +331,13 @@ def from_lecroy_remote(cls, channel_number: int, ip_address: str, channel_label:
285331
:return: Scope object with collected data
286332
:rtype: 'Scope'
287333
"""
334+
if not isinstance(channel_number, int):
335+
raise TypeError("channel_number must be type int.")
336+
if not isinstance(ip_address, str):
337+
raise TypeError("ip_address must be type str.")
338+
if not isinstance(channel_label, str):
339+
raise TypeError("channel_label must be type str.")
340+
288341
channel_source = "LeCroy scope"
289342

290343
scope = LecroyScope(ip_address)
@@ -374,6 +427,11 @@ def from_geckocircuits(cls, txt_datafile: str, f0: Optional[float] = None) -> Li
374427
:return: List of Channels
375428
:rtype: list[Scope]
376429
"""
430+
if not isinstance(txt_datafile, str):
431+
raise TypeError("txt_datafile must be type str to show the full filepath.")
432+
if not isinstance(f0, (float, int)) != f0 is not None:
433+
raise TypeError("f0 must be type float/int/None.")
434+
377435
channel_source = 'GeckoCIRCUITS simulation'
378436

379437
# Read variables from first line in gecko output file
@@ -419,6 +477,13 @@ def power(cls, channel_voltage: 'Scope', channel_current: 'Scope', channel_label
419477
:return: power in a dataset
420478
:rtype: Scope
421479
"""
480+
if not isinstance(channel_voltage, Scope):
481+
raise TypeError("channel_voltage must be type Scope.")
482+
if not isinstance(channel_current, Scope):
483+
raise TypeError("channel_current must be type Scope.")
484+
if not isinstance(channel_label, str) != channel_label is not None:
485+
raise TypeError("channel_label must be type str or None.")
486+
422487
channel_data = channel_voltage.channel_data * channel_current.channel_data
423488
if channel_label is None and channel_voltage.channel_label is not None \
424489
and channel_current.channel_label is not None:
@@ -442,6 +507,10 @@ def integrate(cls, channel_power: 'Scope', channel_label: Optional[str] = None):
442507
:return: returns a scope-class, what integrates the input values
443508
:rtype: Scope
444509
"""
510+
if not isinstance(channel_power, Scope):
511+
raise TypeError("channel_power must be type Scope.")
512+
if not isinstance(channel_label, str):
513+
raise TypeError("channel_label must be type str.")
445514
channel_energy = np.array([])
446515
timestep = channel_power.channel_time[2] - channel_power.channel_time[1]
447516
for count, _ in enumerate(channel_power.channel_time):
@@ -472,6 +541,8 @@ def add(cls, *channels: 'Scope') -> 'Scope':
472541
channel_data_result = np.zeros_like(channels[0].channel_data)
473542
channel_label_result = ''
474543
for channel in channels:
544+
if not isinstance(channel, Scope):
545+
raise TypeError("channel must be type Scope.")
475546
if channel.channel_time.all() != channels[0].channel_time.all():
476547
raise ValueError("Can not add data. Different Channel.channel_time length!")
477548
channel_data_result += channel.channel_data
@@ -497,6 +568,8 @@ def subtract(cls, *channels: 'Scope') -> 'Scope':
497568
channel_data_result = np.zeros_like(channels[0].channel_data)
498569
channel_label_result = ''
499570
for channel_count, channel in enumerate(channels):
571+
if not isinstance(channel, Scope):
572+
raise TypeError("channel must be type Scope.")
500573
if channel.channel_time.all() != channels[0].channel_time.all():
501574
raise ValueError("Can not add data. Different Channel.channel_time length!")
502575
if channel_count == 0:
@@ -677,6 +750,8 @@ def compare_channels(cls, *channel_datasets: 'Scope', shift: Optional[List[Union
677750
timebase = 's'
678751

679752
for count, channel_dataset in enumerate(channel_datasets):
753+
if not isinstance(channel_dataset, Scope):
754+
raise TypeError("channel_dataset must be type Scope.")
680755
modified_time = channel_dataset.channel_time
681756
modified_data = channel_dataset.channel_data
682757

@@ -717,12 +792,14 @@ def fft(self, plot: bool = True):
717792
>>> channel = pss.Scope.from_numpy(np.array([[0, 5e-3, 10e-3, 15e-3, 20e-3], [1, -1, 1, -1, 1]]), f0=100000, mode='time')
718793
>>> channel.fft()
719794
"""
795+
if not isinstance(plot, bool):
796+
raise TypeError("plot must be type bool.")
720797
period_vector = np.array([self.channel_time, self.channel_data])
721798

722799
return functions.fft(period_vector, mode='time', plot=plot)
723800

724-
def short_to_period(self, f0: Optional[float] = None, time_period: Optional[float] = None,
725-
start_time: Optional[float] = None):
801+
def short_to_period(self, f0: Union[float, int, None] = None, time_period: Union[float, int, None] = None,
802+
start_time: Union[float, int, None] = None):
726803
"""Short a given Scope object to a period.
727804
728805
:param f0: frequency in Hz
@@ -732,6 +809,13 @@ def short_to_period(self, f0: Optional[float] = None, time_period: Optional[floa
732809
:param start_time: start time in seconds
733810
:type start_time: float
734811
"""
812+
if not isinstance(f0, (float, int)) != f0 is not None:
813+
raise TypeError("f0 must be type float/int/None.")
814+
if not isinstance(time_period, (float, int)) != f0 is not None:
815+
raise TypeError("time_period must be type float/int/None.")
816+
if not isinstance(start_time, (float, int)) != f0 is not None:
817+
raise TypeError("start_time must be type float/int/None.")
818+
735819
if start_time is None:
736820
start_time = self.channel_time[0]
737821
# check for correct input parameter
@@ -816,7 +900,10 @@ def save(figure: plt.figure, fig_name: str):
816900
:param fig_name: figure name for pdf file naming
817901
:type fig_name: str
818902
"""
819-
figure.savefig(f"{fig_name}.pdf")
903+
if isinstance(fig_name, str):
904+
figure.savefig(f"{fig_name}.pdf")
905+
else:
906+
raise TypeError("figure name must be of type str.")
820907

821908

822909
if __name__ == '__main__':

0 commit comments

Comments
 (0)