Создание пользовательских приложений в Engee
Проект 1: Исследование квадратичной функции
Описание проекта
Пользуясь сведениями, полученными в предыдущих разделах, вы создадите приложение, в котором пользователь с помощью ползунков задает коэффициенты , и квадратичной функции
Приложение строит график этой функции. При изменении положения любого из ползунков график автоматически перестраивается. При нажатии на кнопку Найти корни вычисляются корни этой функции, т.е. находятся действительные корни квадратного уравнения
Корни квадратного уравнения вычисляются по формулам:
где – дискриминант:
Если , то выводится текстовое сообщение "Действительных корней нет".
✏️Задание 1
Начните создание приложения:
- В папке данного курса создайте скрипт
app4.jl. - Добавьте в скрипт следующий код, создающий "пустое" приложение:
using GenieFramework, Stipple, PlotlyBase
@app begin
end
function ui()
end
@page("/", ui)
Создание заголовка приложения
✏️Задание 2
В интерфейсную часть кода с помощью команды h5() добавьте заголовок "Исследование квадратичной функции y=a*x^2+b*x+c".
Решение
using GenieFramework, Stipple, PlotlyBase
@app begin
end
function ui()
h5("Исследование квадратичной функции y=a*x^2+b*x+c"),
end
@page("/", ui)
Ввод коэффициентов
✏️Задание 3
Добавьте в приложение три структурных блока, состоящих из надписи и ползунка:
- В интерфейсную часть кода с помощью команды
slider()добавьте три ползунка для ввода пользователем значений коэффициентовa,bиcсо следующими параметрами:
|
Коэффициент |
Минимальное значение |
Шаг |
Максимальное значение |
Имя переменной |
Ширина, пикселей |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
С помощью команды cell() объедините каждый ползунок в структурный блок с соответствующей надписью Коэффициент a:,Коэффициент b: и Коэффициент c:.
- В модель данных добавьте описание трех входных реактивных переменных
a,bиcс начальными значениями1.0.
Решение
using GenieFramework, Stipple, PlotlyBase
@app begin
@in a = 1.0
@in b = 1.0
@in c = 1.0
end
function ui()
h5("Исследование квадратичной функции y=a*x^2+b*x+c"),
cell([h6("Коэффициент a:"), slider(-20:0.1:20, :a, label="", style="width:600px")]),
cell([h6("Коэффициент b:"), slider(-20:0.1:20, :b, label="", style="width:600px")]),
cell([h6("Коэффициент c:"), slider(-100:0.1:100, :c, label="", style="width:600px")]),
end
@page("/", ui)
График
✏️Задание 4
Добавьте в приложение график:
-
В основную часть кода (сразу после строки
using ...) добавьте векторx1, элементы которого принимают значения от-20до20с шагом0.01. Этот вектор задает абсциссы точек графика. -
Ниже добавьте описание макета графика с помощью функции
PlotlyBase.Layout(). С помощью параметраtitle = "График квадратичной функции"задайте заголовок графика. Подписи на осях задайте какXиY. Включите отображение сетки. Диапазон значений по оси Ox задайте равным от-20до20, по оси Oy – от-200до200. Задайте ширину графика равной800пикселей, а высоту –550пикселей. -
В модель данных добавьте описание двух выходных переменных, задающих начальное состояние графика (график квадратичной функции с коэффициентами, равными единицам), и макет графика:
-
trace = Plot(scatter(x=x1, y = 1.0.*x1.^2 .+ 1.0.*x1 .+ 1.0, line=attr(color="blue"))), -
layout = layout.
-
-
В интерфейсную часть добавьте полотно графика с помощью функции
plotly()с аргументами:traceиlayout=:layout.
Решение
using GenieFramework, Stipple, PlotlyBase
x1 = [-20:0.01:20;]
layout = PlotlyBase.Layout(
title = "График квадратичной функции",
xaxis=attr(title="X", showgrid=true, range=[-20, 20]),
yaxis=attr(title="Y", showgrid=true, range=[-200, 200]),
width=800, height=550
)
@app begin
@in a = 1.0
@in b = 1.0
@in c = 1.0
@out trace = Plot(scatter(x=x1, y = 1.0.*x1.^2 .+ 1.0.*x1 .+ 1.0, line=attr(color="blue")))
@out layout = layout
end
function ui()
h5("Исследование квадратичной функции y=a*x^2+b*x+c"),
cell([h6("Коэффициент a:"), slider(-20:0.1:20, :a, label="", style="width:600px")]),
cell([h6("Коэффициент b:"), slider(-20:0.1:20, :b, label="", style="width:600px")]),
cell([h6("Коэффициент c:"), slider(-100:0.1:100, :c, label="", style="width:600px")]),
plotly(:trace, layout=:layout)
end
@page("/", ui)
Кнопка Найти корни
✏️Задание 5
Добавьте в приложение кнопку:
- В интерфейсную часть кода с помощью команды
btn()добавьте кнопку с надписьюНайти корни. Логическую переменную, описывающую нажатие кнопки, назовитеButton_process. Цвет кнопки задайте равным"primary", а ширину –200пикселей. - В модель данных добавьте описание входной переменной
Button_processс начальным значениемfalse.
Решение
using GenieFramework, Stipple, PlotlyBase
x1 = [-20:0.01:20;]
layout = PlotlyBase.Layout(
title = "График квадратичной функции",
xaxis=attr(title="X", showgrid=true, range=[-20, 20]),
yaxis=attr(title="Y", showgrid=true, range=[-200, 200]),
width=800, height=550
)
@app begin
@in a = 1.0
@in b = 1.0
@in c = 1.0
@in Button_process = false
@out trace = Plot(scatter(x=x1, y = 1.0.*x1.^2 .+ 1.0.*x1 .+ 1.0, line=attr(color="blue")))
@out layout = layout
end
function ui()
h5("Исследование квадратичной функции y=a*x^2+b*x+c"),
cell([h6("Коэффициент a:"), slider(-20:0.1:20, :a, label="", style="width:600px")]),
cell([h6("Коэффициент b:"), slider(-20:0.1:20, :b, label="", style="width:600px")]),
cell([h6("Коэффициент c:"), slider(-100:0.1:100, :c, label="", style="width:600px")]),
btn("Найти корни", @click(:Button_process), color = "primary", style="width:200px"),
plotly(:trace, layout=:layout)
end
@page("/", ui)
Обработчик нажатия кнопки
✏️Задание 6
Добавьте в приложение обработчик нажатия кнопки:
-
В модель данных добавьте описание трех выходных переменных:
root1– первый корень квадратного уравнения, с начальным значением0.0;root2– второй корень квадратного уравнения, с начальным значением0.0;noroots– текстовая переменная, которая принимает значение"Действительных корней нет"в случае отрицательного дискриминанта, и значение""(пустая строка) в противном случае. Начальное значение задайте равным"".
-
В модель данных (после описания реактивных переменных) добавьте макрос
@onbutton– обработчик нажатия кнопки. В нем будет выполняться расчет корней квадратного уравнения.
@onbutton Button_process begin
D = b^2-4*a*c
if D >= 0
root1 = (-b-sqrt(D))/(2*a)
root2 = (-b+sqrt(D))/(2*a)
noroots = ""
else
root1 = 0.0
root2 = 0.0
noroots = "Действительных корней нет"
end
end
Сначала вычисляется дискриминант. Если он неотрицательный, то вычисляются корни root1 и root2, а переменная noroots становится пустой строкой. Если дискриминант отрицательный, то переменная noroots принимает значение "Действительных корней нет", а переменные root1 и root2 обнуляются.
Решение
using GenieFramework, Stipple, PlotlyBase
x1 = [-20:0.01:20;]
layout = PlotlyBase.Layout(
title = "График квадратичной функции",
xaxis=attr(title="X", showgrid=true, range=[-20, 20]),
yaxis=attr(title="Y", showgrid=true, range=[-200, 200]),
width=800, height=550
)
@app begin
@in a = 1.0
@in b = 1.0
@in c = 1.0
@in Button_process = false
@out root1 = 0.0
@out root2 = 0.0
@out noroots = ""
@out trace = Plot(scatter(x=x1, y = 1.0.*x1.^2 .+ 1.0.*x1 .+ 1.0, line=attr(color="blue")))
@out layout = layout
@onbutton Button_process begin
D = b^2-4*a*c
if D >= 0
root1 = (-b-sqrt(D))/(2*a)
root2 = (-b+sqrt(D))/(2*a)
noroots = ""
else
root1 = 0.0
root2 = 0.0
noroots = "Действительных корней нет"
end
end
end
function ui()
h5("Исследование квадратичной функции y=a*x^2+b*x+c"),
cell([h6("Коэффициент a:"), slider(-20:0.1:20, :a, label="", style="width:600px")]),
cell([h6("Коэффициент b:"), slider(-20:0.1:20, :b, label="", style="width:600px")]),
cell([h6("Коэффициент c:"), slider(-100:0.1:100, :c, label="", style="width:600px")]),
btn("Найти корни", @click(:Button_process), color = "primary", style="width:200px"),
plotly(:trace, layout=:layout)
end
@page("/", ui)
Вывод результатов расчета на экран
✏️Задание 7
Вычисленные корни нужно вывести на экран. Если уравнение не имеет действительных корней, то нужно вывести сообщение об этом.
В модель данных добавьте три текстовых поля с помощью команды textfield(). Задайте следующие параметры текстовых полей:
| Номер текстового поля | Надпись | Выводимая переменная | Ширина, пикселей |
|---|---|---|---|
| 1 | "x1=" |
root1 |
400 |
| 2 | "x2=" |
root2 |
400 |
| 3 | "" |
noroots |
400 |
Решение
using GenieFramework, Stipple, PlotlyBase
x1 = [-20:0.01:20;]
layout = PlotlyBase.Layout(
title = "График квадратичной функции",
xaxis=attr(title="X", showgrid=true, range=[-20, 20]),
yaxis=attr(title="Y", showgrid=true, range=[-200, 200]),
width=800, height=550
)
@app begin
@in a = 1.0
@in b = 1.0
@in c = 1.0
@in Button_process = false
@out root1 = 0.0
@out root2 = 0.0
@out noroots = ""
@out trace = Plot(scatter(x=x1, y = 1.0.*x1.^2 .+ 1.0.*x1 .+ 1.0, line=attr(color="blue")))
@out layout = layout
@onbutton Button_process begin
D = b^2-4*a*c
if D >= 0
root1 = (-b-sqrt(D))/(2*a)
root2 = (-b+sqrt(D))/(2*a)
noroots = ""
else
root1 = 0.0
root2 = 0.0
noroots = "Действительных корней нет"
end
end
end
function ui()
h5("Исследование квадратичной функции y=a*x^2+b*x+c"),
cell([h6("Коэффициент a:"), slider(-20:0.1:20, :a, label="", style="width:600px")]),
cell([h6("Коэффициент b:"), slider(-20:0.1:20, :b, label="", style="width:600px")]),
cell([h6("Коэффициент c:"), slider(-100:0.1:100, :c, label="", style="width:600px")]),
btn("Найти корни", @click(:Button_process), color = "primary", style="width:200px"),
textfield("x1=", :root1, style="width:400px"),
textfield("x2=", :root2, style="width:400px"),
textfield("", :noroots, style="width:400px"),
plotly(:trace, layout=:layout)
end
@page("/", ui)
Реактивная логика
✏️Задание 8
Вам нужно обеспечить автоматическую перерисовку графика при изменении значений любого из коэффициентов квадратичной функции. Для этого создайте макрос @onchange – обработчик изменения положения ползунков.
В модель данных добавьте макрос @onchange, который при изменении значений переменной a, b или c создает новый график функции с текущими значениями коэффициентов a, b и c:
@onchange a, b, c begin
trace = Plot(scatter(x=x1, y = a*x1.^2 .+ b*x1 .+ c, line=attr(color="blue")))
end
Решение
using GenieFramework, Stipple, PlotlyBase
x1 = [-20:0.01:20;]
layout = PlotlyBase.Layout(
title = "График квадратичной функции",
xaxis=attr(title="X", showgrid=true, range=[-20, 20]),
yaxis=attr(title="Y", showgrid=true, range=[-200, 200]),
width=800, height=550
)
@app begin
@in a = 1.0
@in b = 1.0
@in c = 1.0
@in Button_process = false
@out root1 = 0.0
@out root2 = 0.0
@out noroots = ""
@out trace = Plot(scatter(x=x1, y = 1.0.*x1.^2 .+ 1.0.*x1 .+ 1.0, line=attr(color="blue")))
@out layout = layout
@onchange a, b, c begin
trace = Plot(scatter(x=x1, y = a*x1.^2 .+ b*x1 .+ c, line=attr(color="blue")))
end
@onbutton Button_process begin
D = b^2-4*a*c
if D >= 0
root1 = (-b-sqrt(D))/(2*a)
root2 = (-b+sqrt(D))/(2*a)
noroots = ""
else
root1 = 0.0
root2 = 0.0
noroots = "Действительных корней нет"
end
end
end
function ui()
h5("Исследование квадратичной функции y=a*x^2+b*x+c"),
cell([h6("Коэффициент a:"), slider(-20:0.1:20, :a, label="", style="width:600px")]),
cell([h6("Коэффициент b:"), slider(-20:0.1:20, :b, label="", style="width:600px")]),
cell([h6("Коэффициент c:"), slider(-100:0.1:100, :c, label="", style="width:600px")]),
btn("Найти корни", @click(:Button_process), color = "primary", style="width:200px"),
textfield("x1=", :root1, style="width:400px"),
textfield("x2=", :root2, style="width:400px"),
textfield("", :noroots, style="width:400px"),
plotly(:trace, layout=:layout)
end
@page("/", ui)
Расположение элементов интерфейса по строкам и столбцам
✏️Задание 9
Приложение почти готово. Вам осталось расположить элементы интерфейса в два столбца. С помощью команд row() и column() расположите в правом столбце полотно графика, а в левом столбце – все остальные элементы друг под другом: заголовок, три ползунка, кнопка и три текстовых поля. При выполнении этого задания вы можете использовать в качестве образца код приложения, которое вы создавали в разделе "03. Построение графиков с помощью Genie". Ширину обоих столбцов задайте равной 6 единицам.
Решение
using GenieFramework, Stipple, PlotlyBase
x1 = [-20:0.01:20;]
layout = PlotlyBase.Layout(
title = "График квадратичной функции",
xaxis=attr(title="X", showgrid=true, range=[-20, 20]),
yaxis=attr(title="Y", showgrid=true, range=[-200, 200]),
width=800, height=550
)
@app begin
@in a = 1.0
@in b = 1.0
@in c = 1.0
@in Button_process = false
@out root1 = 0.0
@out root2 = 0.0
@out noroots = ""
@out trace = Plot(scatter(x=x1, y = 1.0.*x1.^2 .+ 1.0.*x1 .+ 1.0, line=attr(color="blue")))
@out layout = layout
@onchange a, b, c begin
trace = Plot(scatter(x=x1, y = a*x1.^2 .+ b*x1 .+ c, line=attr(color="blue")))
end
@onbutton Button_process begin
D = b^2-4*a*c
if D >= 0
root1 = (-b-sqrt(D))/(2*a)
root2 = (-b+sqrt(D))/(2*a)
noroots = ""
else
root1 = 0.0
root2 = 0.0
noroots = "Действительных корней нет"
end
end
end
function ui()
row([
column([
h5("Исследование квадратичной функции y=a*x^2+b*x+c"),
cell([h6("Коэффициент a:"), slider(-20:0.1:20, :a, label="", style="width:600px")]),
cell([h6("Коэффициент b:"), slider(-20:0.1:20, :b, label="", style="width:600px")]),
cell([h6("Коэффициент c:"), slider(-100:0.1:100, :c, label="", style="width:600px")]),
btn("Найти корни", @click(:Button_process), color = "primary", style="width:200px"),
textfield("x1=", :root1, style="width:400px"),
textfield("x2=", :root2, style="width:400px"),
textfield("", :noroots, style="width:400px")
], size = 6),
column( plotly(:trace, layout=:layout), size = 6),
])
end
@page("/", ui)
Запуск приложения
✏️Задание 10
Запустите приложение:
- Находясь в папке данного курса, выполните в командной строке следующую команду:
engee.genie.start("app4.jl") - Перейдите по ссылке, появившейся в ячейке вывода. Приложение откроется в новой вкладке браузера.
- Изменяя положение ползунков, проверьте правильность отрисовки графиков, а также правильность расчета корней квадратичной функции.
Решение
Окно приложения: