Тема: введення і виведення даних. Вікна повідомлень, їх використання. Передавання значень між вікном повідомлення і змінними мовою Ruby.
Мета:
По завершенню вивчення учень
Обладнання: ПК із встановленими ОС, текстовим редактором, інтерпретатором мови програмування Ruby.
Структура уроку
Хід уроку
1. Організаційний момент
Вітання з класом. Перевірка присутності і готовності учнів до уроку. Перевірка виконання домашнього завдання.
2. Актуалізація опорних знань
Описати поняття, назви яких виділено жирним шрифтом, і порівняти з очікуваним.
Інтерпретована мова програмування — мова програмування, в якій початковий (сирцевий) код програми не перетворюють попередньо повністю у машинний код для виконання, на відміну від компільованих мов, а виконують рядок за рядком з допомогою спеціальної програми-інтерпретатора.
Тип даних — це деякий клас об`єктів даних разом з набором операцій для створення і роботи з ними і діапазоном допустимих значень.
В кожній мові програмування є певний набір вбудованих типів даних. Зазвичай передбачено засоби визначення інших (невбудованих) типів даних. У мові Ruby розрізнять прості та складні типи даних. До простих відносять числові, логічні та символьні типи даних.
Ієрархія класів Ruby:
Запис діапазону містить 3 складові (вказано у порядку запису):
де початок і кінець — дані одного злічуваного типу даних одного класу. Злічимість означає наявність методу .succ (переходу до наступного елемента).
Ідентифікатор — це назва, яку користувач надає об’єктам (змінним, методам, класам). Ідентифікатори Ruby складаються з літер, цифр і символів підкреслення, але вони не можуть починатись з цифри. Ідентифікатори не можуть містити пробіли, знаки пунктуації або символи, що не відображаються:
При написаннні ідентифікатора враховують регістр: MAX, Max і max — три різні ідентифікатори.
Ключові слова — це зарезервовані ідентифікатори, які використовують для написання вказівок:
_LINE_, _ENCODING_, _FILE_, BEGIN, END, alias, and, begin, break, case, class, def, defined?, do, else, elsif, end, ensure, false, for, if, in, module, next, nil, not, or, redo, rescue,
retry, return, self, super, then, true, undef, unless, until, when, while, yield, break
Величина — одиниця даних, якими оперує програма. Вона має такі властивості:
назва (ідентифікатор) — послідовність літер латиниці, цифр і нижнього підкреслювання «_», на початку — обов'язково літера;
тип — визначає обсяг відведеної пам'яті, можливі дії, правила тлумачення бітів пам'яті та множину допустимих значень;
розмірність — проста або складена (структурована);
значення — елемент множини допустимих значень величини.
Домовленості для позначення області видимості — див. приклад:
var — локальна змінна;
@var — змінна екземпляра (член або поле об'єкта класу);
@@ var — змінна класу;
$var — глобальна змінна.
3. Інструктаж з ТБ
4. Вивчення нового матеріалу
Учні повинні перевіряли роботу програм, змінюючи коди програми, і описували розмовною мовою код програм.
Вказівка puts виводить аргументи по одному в рядку. Наприклад, виконання вказівки:
puts 35, [2, 4, 14], "Текст", 4 * 6
призводить до виведення таких даних:
35 2 4 14 Текст 24
Вказівка puts без аргументів виводить порожній рядок (ознаку кінця рядка).
У мові Ruby є чудова вставляти частини коду Ruby у рядок виведення завдяки конструкції #{…} . Наприклад, виконання вказівки:
puts "2 x 2 = #{2*2}"
призводить до виведення таких даних:
2 x 2 = 4
Вказівка print виводить аргументи в одному рядку. Наприклад, виконання вказівки:
print 35, [2, 4, 14], "Текст", 4 * 6
призводить до виведення таких даних:
352414Текст24
Як бачимо, ця вказівка не розділяє значення при виведенні їх. Тому це потрібно запрограмувати самостійно. Наприклад, таким чином:
print 35, " ", [2, 4, 14], " ", "Текст", " ", 4 * 6
Вказівка p призначена для проміжного виведення даних у процесі налагодження програми — див. приклад:
p 35, [2, 4, 14], "Текст", 4 * 6
з таким результатом:
35 [2, 4, 14] “\222\245\252\341\342” 24
Можливо, це не ідеальний варіант, але число від масиву відрізнити можна.
Вказівка gets призначена для введення даних. Виконання вказівки: a = gets інтерпретатор призупиняє роботу скрипта і чекає введення рядка з клавіатури. Після натискання клавіші Enter змінна а набуває значення введеного рядка (разом з ознакою кінця рядка) і виконання скрипта поновлюється. Ознаку кінця можна відсікти, наприклад, таким чином:
a = gets.chomp
Метод gets має синонім readline:
a = readline
Цей метод трохи відрізняється від gets поведінкою при роботі з файлами, а в іншому вони повністю ідентичні.
Робота з файлами. Файли у програмах відіграють роль сховищ, в яких можна зберігати значення будь-яких змінних. На відміну від створюваних програмою об'єктів файли зберігають дані навіть після виконання програми. Саме тому їх
можна використати для обміну даними між різними програмами або різними запусками однієї і тієї самої програми.
Етапи роботи з файлом:
Реалізація роботи з файлами:
методи класу IO;
перенаправлення потоків за допомогою змінних $stdout, $stdin і $stderr. Якщо їм надати значення об'єктів класу File, то:
Якщо потрібно працювати лише з одним файлом на читання і одним файлом на запис, то зазвичай використовують саме цей спосіб.
Розглянемо спочатку використання класу ІО при роботі з файлами.
Створення нового файлу здійснюють за допомогою методу new класу File:
f = File.new(path; mode)
Тут (рядок тексту) path — це шлях до файлу (абсолютний чи відносний), включаючи назву файлу, mode — режим роботи з файлом (див. далі).
Відкриття наявного файлу здійснюють за допомогою методу open класу File:
f = File.open(path; mode)
(зміст параметрів — той самий).
Режим роботи з файлом:
При використанні того чи іншого режиму потрібно, щоб програма мала право виконувати відповідні операції з файлом. Інакше буде згенеровано помилку.
Закриття файлу здійснюють за допомогою методу close з класу File:
f.close
Якщо файл не закрито програмним засобом, його однаково буде закрито по завершенню програми. Але хорошим тоном вважають закриття файлу, описане у коді програми.
Робота з файлами подібна роботі зі стандартними потоками введення-виведення. Або скажемо так: стандартні потоки введення і виведення (з клавіатури й на екран) є псевдофайлами, з яких зчитують і в які записують дані. Це означає, що працювати з файлами можна за допомогою одних і тих самих методів. Наприклад, gets і puts.
Метод read класу File дозволяє прочитати вміст всьго файлу «одним блоком». Під час його використання не потрібно замислюватися про відкриття чи закриття файлу, бо ці операції приховані всередині методу. Нехай, наприклад, файл
one.txt містить такі три рядки:
перший рядок 255 третій рядок
У результаті виконання такого коду:
f = File.open("one.txt", "r") f.read
буде отримано один рядок:
перший рядок255третій рядок
Метод readline класу File дозволяє окремі рядки файлу. Для файлу one.txt з тим самим вмістом, що й у попередньому прикладі, у результаті виконання такого коду:
f = File.open("one.txt", "r") а1=f.readline а2=f.readline а3=f.readline
буде надано такі значення:
а1="перший рядок" а2=255 a3="третій рядок"
Метод readlines класу File повертає масив, елементами якого є рядки файлу. Для файлу one.txt з тим самим вмістом, що й для прикладу для методу read, у результаті виконання такого коду:
f = File.open("one.txt", "r") а=f.readlines
буде надано таке значення:
а = ["перший рядок", 255, "третій рядок"]
Метод rewind класу File повертає на початок файлу, який читають. Для файлу one.txt з тим самим вмістом, що й для прикладу для методу read, у результаті виконання такого коду:
f = File.open("one.txt", "r") а1=f.readline f.rewind а2=f.readline
буде надано такі значення:
а1="перший рядок" а2="перший рядок"
Методи puts i write класу File найуживаніші при записі до файлу. Основна відмінність між ними полягає у тому, що puts додає ознаку кінця рядка, а write — ні. Наприклад, при виконанні такого коду:
f = File.open("one.txt", "w+") f.puts "first line" f.write "second " f.write "line" f.rewind print f.readlines
отримаємо такий результат виведення на екран:
["first line\n", "second line"]
Розглянемо приклад програми мовою ruby для переводити градусів за Цельсієм у градуси за Фаренгейтом:
c = 100 puts "#{c}°С = #{c*9/5+32}°F"
з таким результатом:
100°С = 212°F
Надамо можливість вводити з клавіатури кількість градусів за шкалою Цельсія:
print "Введіть кількість градусів за шкалою Цельсія: " c = gets.to_f puts "#{c}°С = #{c*9/5+32}°F"
Надамо можливість вибору способу введення значення с: з клавіатури чи з файлу, а результат виводити і на консоль, і у файл t.out. Перед виконанням наступної програми потрібно створити файл t.in, єдиний рядок якого містить запис числа, наприклад, 100.
c = nil while c == nil puts "Виберіть спосіб введення кількості градусів за Цельсієм - натисніть клавішу:" puts " 1 - для введення з клавіатури;" puts " 2 - для зчитування з файлу." v = gets.to_i if v == 1 print "Введіть кількості градусів за Цельсієм: " c = gets.to_f elsif v == 2 c = File.read("t.in").to_f end end f = c*9/5+32 puts "#{c}°С = #{f}°F" o = File.new("t.out","w") o.puts("#{c}°С = #{f}°F") o.close
Перенаправлення потоків введення / виведення
розглянемо на такому прикладі:
$stdin = File.open('t.in', 'r') $stdout = File.open('t.out','w') $stderr = File.open('t.log','a') puts 'Дуже важливі дані' raise 'Примусово викликаємо помилку'
Тут raise — це метод примусового виклику помилки. Після виконання поданої вище програми:
Перейдомо до опису роботи з вікнами повідомлень.
Tk — багатоплатформний (Linux, Windows, MacOS) стандартний графічний інтерфейс користувача (GUI), який використовує Ruby.
Будь-який застосунок Ruby/Tk має завантажити розширення tk, виконавши таку вказівку:
load tk
Будь-яка програма, що використовує Ruby/Tk, має містити вказівку:
require "tk"
Далі інтерфейс програми будують поетапно, розташовуючи у контейнери елементи керування. Наприкінці викликають метод Tk.mainloop, в якому опрацьовують події: переміщення миші, натискання кнопок тощо — див. приклад.
require "tk" # завантаження модуля tk root = TkRoot.new {title "* Заголовок *" } # створено кореневий контейнер методом new TkLabel.new(root) do # cтворено дочірній віджет - мітку TkLabel text 'Текст повідомлення!' # текст повідомлення pack {padx 15; pady 15; side 'left' } # відносні розміри мітки та її розташування на екрані end Tk.mainloop
Результат виконання цієї програми (при ОС Linux Mint 18.1 Serena Mate) такий:
Перетягнувши межі, можна отримати таке:
Класи елементів керування Ruby / Tk
Розташування елементів керування здійснють одним з таких методів:
Приклади використання елементів керування Ruby / Tk
l = TkLabel.new { text "Текс напису" # Створення напису l grid('row'=>0, 'column'=>0, 'columnspan'=> 3)# з розташуванням у таблиці, почикаючи з клітини # рядка 0 і стовпчика 0 у 3 клітинах по горизонталі background "#ffff00" # жовте тло foreground "navy" # темно-синій колір тексту font TkFont.new('ubuntu 14 italic bold underline') # шрифт } e = TkEntry.new { # Створення поля введення е width 3 # шириною 3 символи background "#ffffff" # білий колір тла grid('row'=>2, 'column'=>1) # розташування поля у клітині таблиці } # у рядку 2 і стовпчику 1 e.gets # повертає рядок поля введення е e.delete(0,9) # вилучення символів 0-9 рядка поля введення е b = TkButton.new { text "Натискай" # Створення кнопки b з написом: "Натискай" grid('row'=>2, 'column'=>2) # з розташуванням у клітині таблиці } # у рядку 2 і стовпчику 2 # Обробники подій, породжених діями з об'єктом b b.bind("ButtonPress-1") {} # натискання кнопки 1 (-1 можна не вказувати для ЛК) b.bind("ButtonRelease-3") {} # відпускання кнопки 3 b.bind("Motion") {} # пересування вказівника миші
Для глибшого вивчення можливостей властивостей і методів елементів керування Ruby / Tk радимо використати опис (англійською) 1, 2, 3 з прикладами кодів та ілюстраціями. Це дасть можливість створювати інтерфейси без наочного програмування у середовищі Glade, що буде розглянуто пізніше. Тобто швидше при наявності відповідних навичок роботи з клавіатурою та уміння уявляти структуру інтерфейсу.
Зосередимося поки на віках повідомлень і вікнах діалогу, що відповідає темі заняття.
Властивості класу вікон повідомлень Tk.messageBox
(типу String, після тлумачення вказано можливі значення)
type — тип повідомлення: abortretryignore, ok, okcancel, retrycancel, yesno, yesnocancel. Цей атрибут впливає на значення наступного параметру default;
default — тип кнопки: abort, retry, ignore, ok, cancel, yes, no (залежно від типу повідомлення);
message — текст повідомлення;
title — текст заголовку вікна повідомленння.
Наприклад, програма:
require 'tk' root = TkRoot.new root.title = "Первинне вікно" m = Tk.messageBox ({ 'icon' =>'question', 'message'=>'Текст повідомлення', 'title' =>'Вікно повідомлення', 'type' =>'abortretryignore' }) case m when 'abort' puts 'abort' when 'retry' puts 'retry' when 'ignore' puts 'ignore' end Tk.mainloop
має такий результат:
При натисканні на кнопку відповідний рядок буде виведено на екран.
Вікно діалогу використовують з метою отримати певні дані від користувача, повідомити йому про подію, що відбулася, підтвердити дію тощо. Ruby / Tk містить декілька класів вікон діалогу. Розглянемо чотири з них:
Наступний приклад демонструє використання вікна діалогу для відкриття файлу і виведення повного шляху до нього.
require "tk" root = TkRoot.new root.title = "Первинне вікно" button_click = Proc.new {puts Tk::getOpenFile} button = TkButton.new(root) do text "Вибрати файл" pack("side" => "left", "padx"=> "50", "pady"=> "50") end button.command = button_click Tk.mainloop
Наступний приклад демонструє використання вікна діалогу для збереження файлу і виведення повного шляху до нього.
root = TkRoot.new root.title = "Первинне вікно" button_click = Proc.new {puts Tk::getSaveFile} button = TkButton.new(root) do text "Зберегти файл" pack("side" => "left", "padx"=> "50", "pady"=> "50") end button.command = button_click Tk.mainloop
Наступний приклад демонструє використання вікна діалогу для відкриття теки (до неї потрібно зайти) і виведення повного шляху до неї.
require "tk" root = TkRoot.new root.title = "Первинне вікно" button_click = Proc.new {puts Tk::chooseDirectory} button = TkButton.new(root) do text "Вибрати теку" pack("side" => "left", "padx"=> "50", "pady"=> "50") end button.command = button_click Tk.mainloop
Наступний приклад демонструє використання вікна діалогу для вибору кольору і виведення його (модель RGB).
require "tk" root = TkRoot.new root.title = "Первинне вікно" button_click = Proc.new {puts Tk::chooseColor :initialcolor => '#d6d6d6'} button = TkButton.new(root) do text "Вибрати теку" pack("side" => "left", "padx"=> "50", "pady"=> "50") end button.command = button_click Tk.mainloop
Задання початкового кольору
:initialcolor => '#d6d6d6'
можна не вказувати.
Наступний приклад демонструє використання полів введення TkEntry, напису TkLabel і кнопки введення.
require 'tk' $root = TkRoot.new( :title => "Різниця", :width => 185, :height => 110) Tk.root.bind( TkVirtualEvent.new('Control-c', 'Control-q'), proc{Tk.exit}) l = TkLabel.new{ text "Введіть числа:" } l.place(:x => 10, :y => 10) l.font= TkFont.new(:size => 10) e1 = TkEntry.new v1 = TkVariable.new("зменшуване") e1.textvariable(v1) e1.place(:x => 10, :y => 30) e1.bind("FocusOut") { eval v1.value } e2 = TkEntry.new v2 = TkVariable.new("від'ємник") e2.textvariable(v2) e2.place(:x => 10, :y => 50) e2.bind("FocusOut") { eval v2.value } b = TkButton.new { text "Обчислити" } b.place(:x => 10, :y => 70) b.bind("ButtonPress") { puts v1.value.to_f-v2.value.to_f l.text = (v1.value.to_f-v2.value.to_f) } Tk.mainloop
Проілюструємо можливість форматування елемента керування на прикладі кнопки (у порівнянні з попереднім прикладом змінено лише опис кнопки).
require 'tk' $root = TkRoot.new( :title => "Різниця", :width => 185, :height => 130) Tk.root.bind( TkVirtualEvent.new('Control-c', 'Control-q'), proc{Tk.exit}) l = TkLabel.new{ text "Введіть числа:" } l.place(:x => 10, :y => 10) l.font= TkFont.new(:size => 10) e1 = TkEntry.new v1 = TkVariable.new("зменшуване") e1.textvariable(v1) e1.place(:x => 10, :y => 30) e1.bind("FocusOut") { eval v1.value } e2 = TkEntry.new v2 = TkVariable.new("від'ємник") e2.textvariable(v2) e2.place(:x => 10, :y => 50) e2.bind("FocusOut") { eval v2.value } b = TkButton.new($root) do text "Обчислити" borderwidth 3 underline 0 state "normal" cursor "watch" font TkFont.new('times 20 bold') foreground "green" activebackground "white" relief "groove" command(proc { puts v1.value.to_f-v2.value.to_f l.text = (v1.value.to_f-v2.value.to_f) }) place(:x => 10, :y => 70) end Tk.mainloop
5. Підбиття підсумків уроку
Виставлення оцінок.
6. Домашнє завдання
Скласти програму з графічним інтерфейсом з двома полями для введення значень цілих чисел і кнопкою для виклику вікна діалогу вибору файлу для запису різниці введених чисел.
Текст упорядкувала Жук Алла Володимирівна, вчитель інформатики МНВК Святошинського району міста Києва, під час виконання випускної роботи на курсах підвищення кваліфікації з 30.10.2017 по 03.11.2017.