From 189d5214683e4b24e1b36a1c5338808083e34669 Mon Sep 17 00:00:00 2001 From: LeoBarreiro Date: Fri, 27 Aug 2021 05:47:07 -0300 Subject: [PATCH] Clase dimmer implementada. Faltan optimizaciones de calculos repetidos en el plotter pero no vienen al caso. --- dimmer.ipynb | 94 ------------------------ dimmer.py | 72 +++++++++++-------- main.py | 118 +++++++++++++----------------- rms_vs_tinterrupt.ipynb | 156 ++++++++++++---------------------------- test_properties.py | 42 +++++++++++ 5 files changed, 180 insertions(+), 302 deletions(-) delete mode 100644 dimmer.ipynb create mode 100644 test_properties.py diff --git a/dimmer.ipynb b/dimmer.ipynb deleted file mode 100644 index f2354fc..0000000 --- a/dimmer.ipynb +++ /dev/null @@ -1,94 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "source": [ - "\r\n" - ], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": 1, - "source": [ - "from dimmer import Dimmer\r\n", - "import matplotlib.pyplot as plt\r\n", - "import numpy as np\r\n", - "\r\n", - "dimmer = Dimmer(frec=1, amp=1)" - ], - "outputs": [], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": 3, - "source": [ - "print(f'Duty 100% = {dimmer.convert_duty_rms(100):.4f} v')\r\n", - "print(f'Rms 220v = {dimmer.convert_rms_duty(220):.4f} %')\r\n", - "print(f'amplitud = {dimmer.amplitud}')\r\n", - "print(f'convert_duty_rms = {dimmer.convert_duty_rms(100)}')\r\n", - "print(f'convert_rms_duty = {dimmer.convert_rms_duty(0.7)}')\r\n", - "print(f'frequency = {dimmer.frequency}')\r\n", - "print(f'solve_tint_for_duty = {dimmer.solve_tint_for_duty(100)}')\r\n", - "print(f'time_interrupt = {dimmer.time_interrupt}')\r\n", - "print(f'v_dimmer = {dimmer.v_dimmer(0.1)}')\r\n", - "print(f'_v_sine = {dimmer._v_sine(0.1)}')\r\n", - "print(f'vrms_num = {dimmer.vrms_num()}')\r\n", - "print(f'vrms_simbolic = {dimmer.vrms_simbolic()}')" - ], - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "Duty 100% = 70.7107 v\n", - "Rms 220v = 31112.6984 %\n", - "amplitud = 1\n", - "convert_duty_rms = 70.71067811865476\n", - "convert_rms_duty = 98.99494936611664\n", - "frequency = 1\n", - "solve_tint_for_duty = 0.0\n", - "time_interrupt = 0.5\n", - "v_dimmer = 0\n", - "_v_sine = 0.5877852522924731\n", - "vrms_num = 0.0\n", - "vrms_simbolic = 0.0\n" - ] - } - ], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": null, - "source": [], - "outputs": [], - "metadata": {} - } - ], - "metadata": { - "orig_nbformat": 4, - "language_info": { - "name": "python", - "version": "3.9.1", - "mimetype": "text/x-python", - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "pygments_lexer": "ipython3", - "nbconvert_exporter": "python", - "file_extension": ".py" - }, - "kernelspec": { - "name": "python3", - "display_name": "Python 3.9.1 64-bit ('env': venv)" - }, - "interpreter": { - "hash": "a4046a09f199e48e61396275ea0e14da7d6ee49ffd95343aa82a9cc54eb636e7" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/dimmer.py b/dimmer.py index 2d72f6a..0ab3d98 100644 --- a/dimmer.py +++ b/dimmer.py @@ -4,20 +4,32 @@ class Dimmer: def __init__(self, frec, amp, time_int=0) -> None: - self.frequency = frec - self.amplitud = amp + self.__frequency = frec + self.amplitud = amp self.time_interrupt = time_int - self._periode = 1 / frec - - + self.__periode = 1 / frec + + @property + def frequency(self): return self.__frequency + @property + def periode(self): return self.__periode + + @frequency.setter + def frequency(self, frec): + self.__frequency, self.__periode = frec, 1 / frec + + @periode.setter + def periode(self, periode): + self.__periode, self.__frequency = periode, 1 / periode + def _v_sine(self, t): omega = 2 * np.pi * self.frequency return self.amplitud * np.sin(omega * t) - + def v_dimmer(self, t): - per = self._periode + per = self.periode tint = self.time_interrupt - + if (0 <= t and t < tint): return 0 elif (tint <= t and t < 0.5 * per): @@ -26,51 +38,55 @@ def v_dimmer(self, t): return 0 elif (0.5*per + tint <= t and t < per): return self._v_sine(t) - + def vrms_num(self): - t_series = np.arange(0, self._periode, self._periode / 200) + t_series = np.arange(0, self.periode, self.periode / 200) v_series = [self.v_dimmer(t) for t in t_series] - v_sum = 0 + v_sum = 0 for i in v_series: v_sum = v_sum + i**2 rms = np.sqrt(v_sum / len(v_series)) return rms - + def vrms_simbolic(self): amp, omega = self.amplitud, 2 * np.pi * self.frequency - per, tint = self._periode, self.time_interrupt - T1, T2 = 0, per + per, tint = self.periode, self.time_interrupt + T1, T2 = 0, per def sine_integrate(t): - int_a = amp ** 2 - int_b = t / 2 - int_c = (np.sin(2*t*omega) / (4*omega)) + int_a = amp ** 2 + int_b = t / 2 + int_c = (np.sin(2*t*omega) / (4*omega)) sine_int = int_a * (int_b - int_c) return sine_int - rms_a = 1 / (T2 - T1) + rms_a = 1 / (T2 - T1) rms_b1 = sine_integrate(T2 / 2) rms_b2 = sine_integrate(tint) - rms_b = (rms_b1 - rms_b2) * 2 - rms = np.sqrt(rms_a * rms_b) + rms_b = (rms_b1 - rms_b2) * 2 + rms = np.sqrt(rms_a * rms_b) return rms - + def convert_rms_duty(self, vrms): - vrms_max = np.sqrt(2) * 0.5 * self.amplitud + vrms_max = np.sqrt(2) * 0.5 * self.amplitud vrms_duty = 100 * vrms / vrms_max return vrms_duty - + def convert_duty_rms(self, vrms_duty): vrms_max = np.sqrt(2) * 0.5 * self.amplitud - vrms = vrms_duty * vrms_max + vrms = vrms_duty * vrms_max return vrms - + def solve_tint_for_duty(self, duty_perc): + # HACK: Se respalda el estado del time interrupt porque se utiliza calacular. Al final se restaura. + time_interrupt_backup = self.time_interrupt + def function(tint, bias=0): self.time_interrupt = tint - vrms_max = np.sqrt(2) * 0.5 * self.amplitud + vrms_max = np.sqrt(2) * 0.5 * self.amplitud vrms_duty = self.vrms_simbolic() / vrms_max return vrms_duty - bias - root = bisect(function, 0, self._periode * 0.5, args=(duty_perc / 100)) + root = bisect(function, 0, self.periode * 0.5, args=(duty_perc / 100)) + + self.time_interrupt = time_interrupt_backup return root - \ No newline at end of file diff --git a/main.py b/main.py index 4d382a7..ae41080 100644 --- a/main.py +++ b/main.py @@ -4,113 +4,91 @@ from scipy.optimize import bisect from functions import * +from dimmer import Dimmer + +dimmer = Dimmer(frec=50, amp=1) def main(): for i in range(100+1): - print("duty([per/2] * {:>14.10f}%)= {:>6.2f}%".format(solve_tInt(i), i)) - + tint = dimmer.solve_tint_for_duty(i) + print(f"duty({tint*1e3:>13.10f} ms)= {i:>6.2f}%") init_plot() -def gen_data(tInt_perc=50, frec=1, amp=1): - samples = 100 - periode = 1 / frec - t = np.linspace(0, periode, samples) - v_dimmer = [fun_Dimmer(ti, tInt_perc, frec, amp) for ti in t] - rms_dimmer = fun_rms_simbolic(tInt_perc, frec, amp) * np.ones(samples) - return [t, v_dimmer, rms_dimmer] - - def init_plot(): global fig, ax1, l1, l2 - t_series, vt_series, rms_series = gen_data() + t_serie, v_serie, vrms_serie = gen_data() plt.ion() fig, ax1 = plt.subplots(figsize=(6, 6)) plt.subplots_adjust(bottom=0.35, top=0.95, right=0.89, wspace=0, hspace=0) - l1, = plt.plot(t_series, vt_series) - l2, = plt.plot(t_series, rms_series) + l1, = plt.plot(t_serie, v_serie) + l2, = plt.plot(t_serie, vrms_serie) plt.grid(True) update_plot() setting_sliders() ax1.set_ylabel(r'Amplitud [v]') - secax_y = ax1.secondary_yaxis( - 'right', functions=(rms_to_duty, duty_to_rms)) + secax_y = ax1.secondary_yaxis('right', functions=( + dimmer.convert_rms_duty, dimmer.convert_rms_duty)) secax_y.set_ylabel(r'Duty [%]') plt.show(block=True) -def update_plot(tInt_perc=50, frec=1, ampl=1): +def gen_data(): + t_serie = np.linspace(0, dimmer.periode, 100) + v_serie = [dimmer.v_dimmer(t) for t in t_serie] + vrms_serie = dimmer.vrms_simbolic() * np.ones(len(t_serie)) + return [t_serie, v_serie, vrms_serie] + + +def update_plot(): global fig, ax1, l1, l2 - t_series, vt_series, rms_series = gen_data(tInt_perc, frec, ampl) + t_serie, v_serie, vrms_serie = gen_data() # Plot data - l1.set_xdata(t_series), l2.set_xdata(t_series) - l1.set_ydata(vt_series), l2.set_ydata(rms_series) + l1.set_xdata(t_serie), l2.set_xdata(t_serie) + l1.set_ydata(v_serie), l2.set_ydata(vrms_serie) # Update legend sine_str = r'$v(t) = \mathcal{A} \mathrm{sin}(2 \omega t)$' - rms_str = "RMS: {:.5f}".format(rms_series[0]) + rms_str = "RMS: {:.5f}".format(vrms_serie[0]) ax1.legend([sine_str, rms_str]) # Update limits - ax1.set_xlim(np.min(0), np.max(1 / frec)) - ax1.set_ylim(-ampl, ampl) + ax1.set_xlim(0, dimmer.periode) + ax1.set_ylim(-dimmer.amplitud, dimmer.amplitud) def setting_sliders(): - def update_sliders(val): - update_plot(slide_tInt.val, slide_frec.val, slide_amp.val) - frec, ampl, tInt_perc = slide_frec.val, slide_amp.val, slide_tInt.val - rms_unit = (np.sqrt(2) / 2) * ampl - rms_value = fun_rms_simbolic(tInt_perc, frec=frec, amp=ampl) / rms_unit - slide_duty.set_val(rms_value * 100) - - def update_slider_duty(val): - tint = solve_tInt(slide_duty.val, slide_frec.val, slide_amp.val) - slide_tInt.set_val(tint) - global ax_frec, ax_amp, ax_tInt, ax_duty, ax_solve global slide_frec, slide_amp, slide_tInt, slide_duty, btn_solve - ax_frec = plt.axes([0.1, 0.10, 0.80, 0.03]) - ax_amp = plt.axes([0.1, 0.15, 0.80, 0.03]) - ax_tInt = plt.axes([0.1, 0.20, 0.80, 0.03]) - ax_duty = plt.axes([0.1, 0.25, 0.6, 0.03]) - ax_solve = plt.axes([0.8, 0.25, 0.1, 0.03]) - slide_frec = Slider(ax_frec, 'Frec', 1.0, 50, valinit=1, valstep=1) - slide_amp = Slider(ax_amp, 'Amp', 1.0, 311, valinit=1, valstep=1) - slide_tInt = Slider(ax_tInt, '%Int', 0.0, 100, valinit=50, valstep=1) - slide_duty = Slider(ax_duty, '%Duty', 0.0, 100, valinit=50, valstep=1) - btn_solve = Button(ax_solve, 'Solve') + + def update_sliders(val): + dimmer.frequency = slide_frec.val + dimmer.amplitud = slide_amp.val + dimmer.time_interrupt = dimmer.periode * 0.5 * slide_tInt.val / 100 + vrms_max = np.sqrt(2) * 0.5 * dimmer.amplitud + slide_duty.set_val(100 * dimmer.vrms_simbolic() / vrms_max) + update_plot() + + def do_tint_solve(val): + tint = dimmer.solve_tint_for_duty(slide_duty.val) + slide_tInt.set_val(100 * tint / (dimmer.periode * 0.5)) + + ax_frec = plt.axes([0.12, 0.10, 0.80, 0.03]) + ax_amp = plt.axes([0.12, 0.15, 0.80, 0.03]) + ax_tInt = plt.axes([0.12, 0.20, 0.80, 0.03]) + ax_duty = plt.axes([0.12, 0.25, 0.60, 0.03]) + ax_solve = plt.axes([0.8, 0.25, 0.10, 0.03]) + slide_frec = Slider(ax_frec, 'Frec Hz', 1.0, 50, valinit=1, valstep=1) + slide_amp = Slider(ax_amp, 'Ampl V', 1.0, 311, valinit=1, valstep=1) + slide_tInt = Slider(ax_tInt, 'Int. %', 0.0, 100, valinit=50, valstep=1) + slide_duty = Slider(ax_duty, 'Duty %', 0.0, 100, valinit=50, valstep=1) + btn_solve = Button(ax_solve,'Solve') slide_frec.on_changed(update_sliders) slide_amp.on_changed(update_sliders) slide_tInt.on_changed(update_sliders) - # slide_duty.on_changed(solve_tInt) - btn_solve.on_clicked(update_slider_duty) - - -def rms_to_duty(x): - vrms = x - # vrms = fun_rms_simbolic(slide_tInt.val, slide_frec.val, slide_amp.val) - vrms_max = np.sqrt(2) * 0.5 * slide_amp.val - vrms_duty = 100 * vrms / vrms_max - return vrms_duty - - -def duty_to_rms(x): - vrms_duty = x - vrms_max = np.sqrt(2) * 0.5 * slide_amp.val - vrms = vrms_duty * vrms_max / 100 - return vrms - - -def solve_tInt(duty, frec=1, amp=1): - def function(tInt_perc, bias=0): - rms_unit = (np.sqrt(2) / 2) * amp - rms_value = fun_rms_simbolic(tInt_perc, frec=frec, amp=amp) / rms_unit - return rms_value - bias - root = bisect(function, 0, 100, args=(duty / 100)) - return root + btn_solve.on_clicked(do_tint_solve) if __name__ == "__main__": diff --git a/rms_vs_tinterrupt.ipynb b/rms_vs_tinterrupt.ipynb index 4ac8391..55b7c77 100644 --- a/rms_vs_tinterrupt.ipynb +++ b/rms_vs_tinterrupt.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 8, + "execution_count": 1, "source": [ "import numpy as np\r\n", "import matplotlib.pyplot as plt\r\n", @@ -35,7 +35,7 @@ "text/plain": [ "
" ], - "image/svg+xml": "\r\n\r\n\r\n \r\n \r\n \r\n \r\n 2021-08-25T02:01:55.290193\r\n image/svg+xml\r\n \r\n \r\n Matplotlib v3.4.3, https://matplotlib.org/\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n", + "image/svg+xml": "\r\n\r\n\r\n \r\n \r\n \r\n \r\n 2021-08-25T23:14:59.699897\r\n image/svg+xml\r\n \r\n \r\n Matplotlib v3.4.3, https://matplotlib.org/\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n", "image/png": "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" }, "metadata": { @@ -47,14 +47,14 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 2, "source": [ "from scipy.optimize import newton, bisect\r\n", "root = bisect(function, 0, 100, args=(0.10))\r\n", "\r\n", - "for i in range(100):\r\n", - " root = bisect(function, 0, 100.0, args=(i / 100))\r\n", - " print(\"rms({:.4f}%)= {:.2f}%\".format(root, function(root) * 100))\r\n", + "# for i in range(100):\r\n", + "# root = bisect(function, 0, 100.0, args=(i / 100))\r\n", + "# print(\"rms({:.4f}%)= {:.2f}%\".format(root, function(root) * 100))\r\n", "\r\n", "\r\n", "print(\"rms(half_periode * {:.2f}%)= {:.4f}%\".\r\n", @@ -65,107 +65,7 @@ "output_type": "stream", "name": "stdout", "text": [ - "rms(1/2 per * 100.0000%)= 0.00%\n", - "rms(1/2 per * 97.5220%)= 1.00%\n", - "rms(1/2 per * 96.0640%)= 2.00%\n", - "rms(1/2 per * 94.8385%)= 3.00%\n", - "rms(1/2 per * 93.7422%)= 4.00%\n", - "rms(1/2 per * 92.7319%)= 5.00%\n", - "rms(1/2 per * 91.7846%)= 6.00%\n", - "rms(1/2 per * 90.8861%)= 7.00%\n", - "rms(1/2 per * 90.0268%)= 8.00%\n", - "rms(1/2 per * 89.1999%)= 9.00%\n", - "rms(1/2 per * 88.4004%)= 10.00%\n", - "rms(1/2 per * 87.6242%)= 11.00%\n", - "rms(1/2 per * 86.8684%)= 12.00%\n", - "rms(1/2 per * 86.1305%)= 13.00%\n", - "rms(1/2 per * 85.4083%)= 14.00%\n", - "rms(1/2 per * 84.7001%)= 15.00%\n", - "rms(1/2 per * 84.0045%)= 16.00%\n", - "rms(1/2 per * 83.3202%)= 17.00%\n", - "rms(1/2 per * 82.6461%)= 18.00%\n", - "rms(1/2 per * 81.9813%)= 19.00%\n", - "rms(1/2 per * 81.3248%)= 20.00%\n", - "rms(1/2 per * 80.6759%)= 21.00%\n", - "rms(1/2 per * 80.0340%)= 22.00%\n", - "rms(1/2 per * 79.3984%)= 23.00%\n", - "rms(1/2 per * 78.7686%)= 24.00%\n", - "rms(1/2 per * 78.1440%)= 25.00%\n", - "rms(1/2 per * 77.5243%)= 26.00%\n", - "rms(1/2 per * 76.9088%)= 27.00%\n", - "rms(1/2 per * 76.2973%)= 28.00%\n", - "rms(1/2 per * 75.6894%)= 29.00%\n", - "rms(1/2 per * 75.0847%)= 30.00%\n", - "rms(1/2 per * 74.4829%)= 31.00%\n", - "rms(1/2 per * 73.8836%)= 32.00%\n", - "rms(1/2 per * 73.2866%)= 33.00%\n", - "rms(1/2 per * 72.6916%)= 34.00%\n", - "rms(1/2 per * 72.0983%)= 35.00%\n", - "rms(1/2 per * 71.5064%)= 36.00%\n", - "rms(1/2 per * 70.9157%)= 37.00%\n", - "rms(1/2 per * 70.3259%)= 38.00%\n", - "rms(1/2 per * 69.7368%)= 39.00%\n", - "rms(1/2 per * 69.1482%)= 40.00%\n", - "rms(1/2 per * 68.5598%)= 41.00%\n", - "rms(1/2 per * 67.9714%)= 42.00%\n", - "rms(1/2 per * 67.3828%)= 43.00%\n", - "rms(1/2 per * 66.7937%)= 44.00%\n", - "rms(1/2 per * 66.2039%)= 45.00%\n", - "rms(1/2 per * 65.6133%)= 46.00%\n", - "rms(1/2 per * 65.0215%)= 47.00%\n", - "rms(1/2 per * 64.4283%)= 48.00%\n", - "rms(1/2 per * 63.8336%)= 49.00%\n", - "rms(1/2 per * 63.2371%)= 50.00%\n", - "rms(1/2 per * 62.6385%)= 51.00%\n", - "rms(1/2 per * 62.0377%)= 52.00%\n", - "rms(1/2 per * 61.4343%)= 53.00%\n", - "rms(1/2 per * 60.8281%)= 54.00%\n", - "rms(1/2 per * 60.2189%)= 55.00%\n", - "rms(1/2 per * 59.6064%)= 56.00%\n", - "rms(1/2 per * 58.9903%)= 57.00%\n", - "rms(1/2 per * 58.3703%)= 58.00%\n", - "rms(1/2 per * 57.7461%)= 59.00%\n", - "rms(1/2 per * 57.1174%)= 60.00%\n", - "rms(1/2 per * 56.4839%)= 61.00%\n", - "rms(1/2 per * 55.8453%)= 62.00%\n", - "rms(1/2 per * 55.2010%)= 63.00%\n", - "rms(1/2 per * 54.5509%)= 64.00%\n", - "rms(1/2 per * 53.8944%)= 65.00%\n", - "rms(1/2 per * 53.2311%)= 66.00%\n", - "rms(1/2 per * 52.5605%)= 67.00%\n", - "rms(1/2 per * 51.8822%)= 68.00%\n", - "rms(1/2 per * 51.1956%)= 69.00%\n", - "rms(1/2 per * 50.5000%)= 70.00%\n", - "rms(1/2 per * 49.7950%)= 71.00%\n", - "rms(1/2 per * 49.0797%)= 72.00%\n", - "rms(1/2 per * 48.3535%)= 73.00%\n", - "rms(1/2 per * 47.6155%)= 74.00%\n", - "rms(1/2 per * 46.8649%)= 75.00%\n", - "rms(1/2 per * 46.1006%)= 76.00%\n", - "rms(1/2 per * 45.3215%)= 77.00%\n", - "rms(1/2 per * 44.5264%)= 78.00%\n", - "rms(1/2 per * 43.7139%)= 79.00%\n", - "rms(1/2 per * 42.8826%)= 80.00%\n", - "rms(1/2 per * 42.0306%)= 81.00%\n", - "rms(1/2 per * 41.1559%)= 82.00%\n", - "rms(1/2 per * 40.2563%)= 83.00%\n", - "rms(1/2 per * 39.3292%)= 84.00%\n", - "rms(1/2 per * 38.3713%)= 85.00%\n", - "rms(1/2 per * 37.3791%)= 86.00%\n", - "rms(1/2 per * 36.3482%)= 87.00%\n", - "rms(1/2 per * 35.2733%)= 88.00%\n", - "rms(1/2 per * 34.1480%)= 89.00%\n", - "rms(1/2 per * 32.9641%)= 90.00%\n", - "rms(1/2 per * 31.7113%)= 91.00%\n", - "rms(1/2 per * 30.3761%)= 92.00%\n", - "rms(1/2 per * 28.9402%)= 93.00%\n", - "rms(1/2 per * 27.3781%)= 94.00%\n", - "rms(1/2 per * 25.6521%)= 95.00%\n", - "rms(1/2 per * 23.7027%)= 96.00%\n", - "rms(1/2 per * 21.4258%)= 97.00%\n", - "rms(1/2 per * 18.6098%)= 98.00%\n", - "rms(1/2 per * 14.6679%)= 99.00%\n", - "rms(half_periode * 14.67%)= 99.0000%\n" + "rms(half_periode * 88.40%)= 10.0000%\n" ] } ], @@ -173,9 +73,45 @@ }, { "cell_type": "code", - "execution_count": null, - "source": [], - "outputs": [], + "execution_count": 3, + "source": [ + "from dimmer import Dimmer\r\n", + "import matplotlib.pyplot as plt\r\n", + "import numpy as np\r\n", + "\r\n", + "dimmer = Dimmer(frec=1, amp=1)\r\n", + "\r\n", + "duty_series = np.arange(0, 100, 1)\r\n", + "rms_series = [dimmer.solve_tint_for_duty(duty) for duty in duty_series]\r\n", + "plt.plot(duty_series, rms_series)\r\n", + "plt.ylabel(\"time [s]\")\r\n", + "plt.xlabel(\"duty [%]\")" + ], + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "Text(0.5, 0, 'duty [%]')" + ] + }, + "metadata": {}, + "execution_count": 3 + }, + { + "output_type": "display_data", + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\r\n\r\n\r\n \r\n \r\n \r\n \r\n 2021-08-25T23:15:00.406406\r\n image/svg+xml\r\n \r\n \r\n Matplotlib v3.4.3, https://matplotlib.org/\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n", + "image/png": "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" + }, + "metadata": { + "needs_background": "light" + } + } + ], "metadata": {} } ], diff --git a/test_properties.py b/test_properties.py new file mode 100644 index 0000000..f72cd75 --- /dev/null +++ b/test_properties.py @@ -0,0 +1,42 @@ +class Onda: + def __init__(self, frec): + self.__frec = frec + self.__per = 1 / frec + + @property + def frec(self): + print(f"getter fre: {self.__frec}") + return self.__frec + + @property + def per(self): + print(f"getter per: {self.__per}") + return self.__per + + + @frec.setter + def frec(self, frec): + self.__frec = frec + self.__per = 1 / frec + print(f"setter fre: {self.frec}") + + @per.setter + def per(self, per): + self.__per = per + self.__frec = 1 / per + print(f"setter per: {self.per}") + + @frec.deleter + def frec(self): + del self.__frec + print("deletter frec") + +sine = Onda(1) +print(f"sine.frec ; {sine.frec}\n") +print(f"sine.per ; {sine.per}\n") +sine.frec = 10 +print(f"sine.frec = 10 ; {sine.frec}\n") +print(f"sine.per ; {sine.per}\n") +sine.per = 0.1 +print(f"sine.per = 0.1 ; {sine.per}\n") +print(f"sine.frec ; {sine.frec}\n") \ No newline at end of file