Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: 1 2 3 4 [5]   Вниз
  Печать  
Автор Тема: Учимся логически думать...  (Прочитано 41286 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #120 : 10-04-2012 07:25 » 

Как начать.

В меню выбираешь Файл/Создать проект (или жмёшь кнопку с оранжевой папкой и зелёным плюсиком). В диалоге в дереве выбираешь Ruby. В соседнем списке выбираешь Ruby Application. Жмёшь кнопку Далее. На следующей странице мастера в поле ProjectName можешь переименовать название проекта, как тебе понравится (но лучше латинскими буквами). Галочку Create main file лучше поставить. Жмёшь кнопку Готово.

Затем у меня случилась какая-то фигня, выдавшая ошибку Жаль Но на результате это не сказалось. Откроется дерево проекта и файл main.rb - код программы. Там сразу уже будет написан "Hello world".

Чтобы запустить программу, надо нажать зелёный треугольник (типа кнопки Play). Внизу в окошке консоли увидишь надпись Hello world - это её написала запущенная программа.

Собственно, всё, можно писать простые программки и смотреть, как они работают.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Sla
Модератор

ua
Online Online
Пол: Мужской

WWW
« Ответ #121 : 10-04-2012 11:11 » 

simka, а ты веб-дизайном не занимаешься?

можно было бы совместить приятное с полезным
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #122 : 10-04-2012 14:19 » 

Dimka, Там версия указана 6.9. Оно будет работать с семеркой?
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #123 : 10-04-2012 14:53 » 

Finch, ну вот я описал всё, как у меня работает. Т.е. я описал свои действия, и заработало. В том числе есть выпадающие подсказки с автодополнением и документация по функциям (правда, на английском). В коментариях пишут, что этот плагин с 7.1.1 ещё не вполне подружили, но базовые вещи работают.

Более того, складывается впечатление, что там настоящий Ruby 1.8.4, а не JRuby.

Начинающему же не нужны Rails, да и рефакторинг тоже не нужен - ни по масштабам работы, ни с педагогической точки зрения.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
simka
Постоялец

ru
Offline Offline
Пол: Женский

« Ответ #124 : 10-04-2012 17:57 » 

Dimka, все сделала как было сказано.

Веб дизайном? Крайне косвенно... логотипчик там кому в векторе наваять, или тому подобное... Как-то хотели заказать оформление сайта, пришлось обломать...
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #125 : 10-04-2012 19:16 » 

simka, я так понял, что всё сработало, включая Hello world.


Тогда некоторые стартовые сведения.


Ruby - такой язык, который понимает разнообразный синтаксис конструкций. Собственно, затем он и был придуман одним японцем. Это не научит дисциплине, зато не будет утомлять на первых порах, на которых и без того забот хватает.

Ruby - язык объектный, следовательно, всё, что есть в программе, является теми или иными объектами. Объекты - тема обширная, поэтому ограничимся самым минимумом. Обычно разделяют понятия "инструкция" (как предписание выполнить известное компьютеру действие) и "данные" - то, над чем компьютер выполняет инструкции.

Например, инструкция "2 + 3": тут "+" - оператор, указывающий компьютеру, какое именно действие надо сделать; "2" и "3" - данные (числа). Инструкция "открыть дверь": тут "открыть" - оператор, описывающий действие, "дверь" - данные для обработки (конкретная дверь). В последнем случае для начала компьютер должен быть обучен тому, что в природе есть двери, и что их можно открывать.

Объект - это увязка вместе данных и каких-то действий по их обработке. Например та же дверь и операция её открытия могут быть увязаны в объект. Тогда говорят, что у объекта "дверь" будет операция "открыть".


Можно считать, что в Ruby все операции относятся к каким-то объектам, а на вид "бесхозные" операции относятся к объекту "программа" или "компьютер".

Например, та же операция "puts", печатающая на экране строчку с текстом, на вид "бесхозная". Если бы компьютер что-то понимал в дверях и их открывании, "бесхозная" операция "открыть дверь" в Ruby выглядела бы так:
Код: (Ruby)
open door
или так
Код: (Ruby)
open(door)
что одно и то же.

На самом деле любая операция - это особый объект, который называется функцией, и он означает примерно то, что мы выше называли подпрограммой. Т.е. он нужен, чтобы "обучить" компьютер делать новую операцию. Новая операция внутри функции записывается алгоритмом, составленным из ранее известных компьютеру операций.

У функции могут быть аргументы или параметры. Они записываются после имени функции через запятую. Либо же они записываются внутри круглых скобок после имени функции тоже через запятую. В строчках выше door (дверь) - это параметр функции open (открыть).

Если же мы имеем делом с объектом, то принадлежащая ему операция (функция) записывается через точку после объекта. Например:
Код: (Ruby)
door.open
или
Код: (Ruby)
door.open();
Здесь у объекта door (дверь), вызывается операция open (открыть). Эта операция не имеет параметров.

В конце любого выражения, являющегося отдельной инструкцией, можно ставить точку с запятой, чтобы отделить предыдущую инструкцию от последующей. Если же договориться, что каждую инструкцию мы будем записывать в отдельной строке, то точки с запятой ставить необязательно.

Ещё один важный момент. Названия в Ruby записываются только латинскими буквами. Причём пока настоятельно рекомендуется использовать лишь строчные буквы. Вывод на экран тоже лучше делать латинскими буквами - так не возникнет сложностей с кодировками.


Помимо операций ещё важно понимать, что такое "константа" и "переменная".

Константа - это прямо в тексте программы указанные данные. Например, 2 - это числовая константа, а "Hello world" (в кавычках) - это текстовая константа (текстовая строка или просто строка). Числовые константы бывают целыми (то же 2) и вещественными (дробными, например, 2.5 - записывается через десятичную точку). Ещё есть логические константы true (правда) и false (ложь), и особая константа nil, которая означает буквально ничего (т.е. пустоту, отсутствие чего бы то ни было).

Переменная - это название, придуманное самим программистом, и означающее место в памяти компьютера, в котором что-то лежит. Программисту не следует выбирать названия, уже что-то означающие в программе. Названия должны быть новыми. Положенное в переменную нечто называется "значением переменной". Когда внутрь переменной помещается конкретное значение, говорят, что происходит присваивание значения переменной. Например:
Код: (Ruby)
x = 2 # переменной x присвоили значение, соответствующее константе 2
y = x # переменной y присвоили значение, соответствующее значению переменной x (т.е. 2, поскольку выше в x положено 2)
x = nil # очистили переменную x от значения, теперь внутри x ничего нет
Здесь "решётка" - это значок, который говорит компьютеру, что текст за ним до конца строки к программе не относится и обрабатываться не должен. Такой текст называется комментарием, и там программист волен писать что угодно без всяких правил. Значок "равно" означает операцию присваивания значения. Важно помнить, что слева находится переменная куда, записывается значение, а справа находится нечто (константа, другая переменная или инструкция), откуда берётся значение для записи.

Теперь назад к пуговицам Улыбаюсь Поскольку компьютер про пуговицы ничего не знает, договоримся, что факт застёгивания пуговицы компьютер будет изображать нам надписью на экране. Например, (по-английски)
button up
или что-то такое. Напомню, что надпись выводит функция puts.


Первое, с чего мы начнём, это напишем программу для застёгивания 4-х пуговиц, а затем будем её улучшать, обсуждая разные тонкости.

Как такая простейшая программа будет выглядеть?
« Последнее редактирование: 10-04-2012 19:23 от Dimka » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
simka
Постоялец

ru
Offline Offline
Пол: Женский

« Ответ #126 : 10-04-2012 23:09 » 

puts "Hello World" свершилось  Улыбаюсь) *на сцену летят цветы в горшках*

Да, прошу прощения за то, что не могу регулярно достаточно времени уделять нахождению здесь и своевременно отвечать всем. Я надеюсь, что вы понимаете. Я очень ценю то время, что вы мне уделяете, и со стороны может показаться, что отношусь наплевательски, но это не так. Просто не всегда есть время и возможность отреагировать сразу, прошу не сердиться... Скромно так...

Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #127 : 11-04-2012 05:06 » 

simka, если бы ты отвечала пореже, это было бы неплохо Ага А то как-то и другие дела есть Улыбаюсь
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
simka
Постоялец

ru
Offline Offline
Пол: Женский

« Ответ #128 : 13-04-2012 12:57 » 

пришлось вообще пропасть временно... ближайшие дни отдохните от меня
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #129 : 13-04-2012 19:00 » 

simka, а то я уж подумал, что как дело от слов перешло к написанию кода, так всё сразу и разонравилось Улыбаюсь Ну подождём.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
simka
Постоялец

ru
Offline Offline
Пол: Женский

« Ответ #130 : 30-05-2012 19:12 » 

Господа, простите за оффтоп, но вынуждена объясниться.  От меня уехал муж, увез с собой часть вещей, коврик, одеяло и... модем. Ну и часть настроения захватил.  Вот, собственно, временно испытывала негативные эмоции ко всему, связанному с программированием и была лишена (как и сейчас) нормального интернета... Но если это надо мне, то за шкирку я себя возьму. Еще раз пардон...
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #131 : 30-05-2012 21:03 » 

simka, одно могу сказать: обычно с возрастом люди становятся чуть мягче и дипломатичнее, а их эмоции начинают лучше дружить с разумом, что и называется мудростью... Чего и остаётся пожелать (мудрости, не возраста).
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
simka
Постоялец

ru
Offline Offline
Пол: Женский

« Ответ #132 : 04-06-2012 20:36 » 

Код: (Ruby)
take(button)
fasten(button)
puts "button up"
repeat(x) # x=item 1 to 4

можете начинать ругаться, но я туплю невероятно(  особенно как предусловие наличия незастегнутой пуговицы описать? и вообще(((( Сколько об стенку не бейся... Должен же быть выход!!!
« Последнее редактирование: 04-06-2012 20:42 от simka » Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #133 : 05-06-2012 05:29 » 

simka, будь проще Улыбаюсь Даже не так: будь намного проще.

Компьютер не знает ни take, ни button, ни fasten с repeat. Компьютер знает только puts "button up".

Компьютеру совершенно фиолетово, button up там или ещё что, и что вообще такое button. Он делает, что сказано, и делает это для человека. Человек хочет получить на экране список действий по застёгиванию 4-х пуговиц. При том, что тип действия пока только один "застегнуть" (button up). Предусловие про расстёгнутые пуговицы задано пока что в голове человека.

Как будет выглядеть программа?
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
simka
Постоялец

ru
Offline Offline
Пол: Женский

« Ответ #134 : 06-06-2012 20:49 » 

Dimka,  не понимаю( Точнее понимаю. но не представляю как это должно выглядеть(((
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #135 : 06-06-2012 22:41 » 

simka, всё должно быть естественным и очевидным.

Итак, мы договорились, что поскольку компьютеру абсолютно всё равно, во что мы с ним играемся, и он всегда готов подыгрывать нам по заданным нами правилам, наше правило: действие "застегнуть пуговицу" выражается надписью на экране "button up".

Важно чётко уяснить, что это пока единственное действие, которое мы рассматриваем. Будем считать, что компьютер ничего другого не умеет, кроме как выполнять это одно действие. Здесь используется концепция "исполнитель". Это субъект, который знает какой-то ограниченный набор операций и понимаемых им команд на выполнение этих операций. Каждый уникальный вид команды понимается исполнителем однозначно и приводит к выполнению одного уникального вида действия. Исполнитель может выполнять команды в их разных сочетаниях. Наша задача: объяснить исполнителю, в каком порядке что делать, для того, чтобы его действия привели к получению нами желаемого нами результата. Т.е. мы при помощи составления программы действий исполнителя управляем поведением исполнителя, чтобы он делал то, что мы хотим.

Мы знаем, как отдельно запрограммировать желаемое нами действие "застегнуть пуговицу". Это строчка в коде программы:
Код: (Ruby)
puts "button up"

Перед нами стоит задача застегнуть 4 пуговицы. Каким будет самое наипростейшее решение этой задачи, исходя из вышеизложенного?
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
simka
Постоялец

ru
Offline Offline
Пол: Женский

« Ответ #136 : 13-06-2012 16:41 » 

собственно, данное действие, повторенное четыре раза. Бред какой-то... %)
Записан
Sla
Модератор

ua
Online Online
Пол: Мужской

WWW
« Ответ #137 : 13-06-2012 16:55 » 

simka, пАчему бред?
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #138 : 13-06-2012 17:24 » 

Чтобы не описывать одинаковые действия их можно выполнять в цикле.

Пример класса кнопки и его применение.
Код: (Ruby)
class Button
  Fasten = 'застегнута'
  Unfasten = 'расстегнута'

  def initialize(name)
    @name = name
    @state = Unfasten
    puts "Создана пуговица '#{@name}'."
  end

  def look
    puts "Пуговица '#{@name}' #{@state}."
  end

  def fasten
    case @state
      when Fasten then
        puts "Пуговица '#{@name}' уже застегнута!"
      when Unfasten then
        @state = Fasten
        puts "Застегиваем пуговицу '#{@name}'."
    end
  end

  def unfasten
    case @state
      when Fasten then
        @state = Unfasten
        puts "Расстегиваем пуговицу '#{@name}'."
      when Unfasten then
        puts "Пуговица '#{@name}' уже расстегнута!"
    end
  end
end

>> buttons = []
>> (1..4).each { |n| buttons.push Button.new(n) }

Создана пуговица '1'.
Создана пуговица '2'.
Создана пуговица '3'.
Создана пуговица '4'.

>> buttons.each { |button| button.look }
Пуговица '1' расстегнута.
Пуговица '2' расстегнута.
Пуговица '3' расстегнута.
Пуговица '4' расстегнута.

>> buttons.each { |button| button.fasten }
Застегиваем пуговицу '1'.
Застегиваем пуговицу '2'.
Застегиваем пуговицу '3'.
Застегиваем пуговицу '4'.

>> buttons.each { |button| button.fasten }
Пуговица '1' уже застегнута!
Пуговица '2' уже застегнута!
Пуговица '3' уже застегнута!
Пуговица '4' уже застегнута!

>> buttons.each { |button| button.look }
Пуговица '1' застегнута.
Пуговица '2' застегнута.
Пуговица '3' застегнута.
Пуговица '4' застегнута.
« Последнее редактирование: 13-06-2012 17:36 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.

Хз, я не очень просто не очень во всё это верю, во всякие там сатурны и прочую поебень.
Sla
Модератор

ua
Online Online
Пол: Мужской

WWW
« Ответ #139 : 13-06-2012 17:33 » 

RXL, гы...
Не тАрАпЫся...
мы еще не знаем что такое цикл
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #140 : 13-06-2012 17:36 » 

Так пора бы уже узнать. Или нет?
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.

Хз, я не очень просто не очень во всё это верю, во всякие там сатурны и прочую поебень.
Sla
Модератор

ua
Online Online
Пол: Мужской

WWW
« Ответ #141 : 13-06-2012 17:39 » 

Не...
только потому что понять что такое цикл не сложно
а вот понять цикл с постусловием и предусловием - к этому Димка и подводит.
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #142 : 13-06-2012 19:55 » 

RXL, не торопись. Sla, и ты не торопись Улыбаюсь


simka, присоединяюсь к вопросу: почему бред?

Ты проникнись простотой и непосредственностью решения. Улыбаюсь Хорошее решение всегда простое, очевидное, краткое, ёмкое, а потому гениальное Улыбаюсь

Код: (Ruby)
puts "button up"
puts "button up"
puts "button up"
puts "button up"

Между тем это программа и стоящий за нею алгоритм для исполнителя.

Любой алгоритм обладает несколькими свойствами, из которых нас сейчас интересовать будут два:
- конечность (т.е. работа исполнителя по алгоритму обязательно должна когда-нибудь завершиться);
- пригодность для решения класса задач.

Поскольку исполнитель умеет делать только 1 действие, то вся наша свобода вариаций заключается лишь в количестве повторов этого действия. Так у нас образуется бесконечное множество алгоритмов, каждый из которых застёгивает конечное количество пуговиц.

Первый алгоритм - вырожденный - ничего не застёгивает.
Второй алгоритм - алгоритм застёгивания 1 пуговицы.
Третий алгорит - алгоритм застёгивания 2 пуговиц.
и т.д.

Ясен пень, это страшно неудобно: каждый раз писать специальный алгоритм для конкретной задачи. Значит нужно обобщить все эти алгоритмы в один, пригодный для решения всего множества подобных задач.

Такой алгоритм будет называться циклическим, поскольку будет уметь повторять действие (или последовательность действий) столько раз, сколько мы захотим. Для этого в Ruby есть специальное выражение. Например:
Код: (Ruby)
4.times do
  # Вместо этого комментария какие-то действия.
end
Смысл тут такой; "4 раза повторить ..."; что повторить - воля программиста, которую он реализует между do и end.

Здесь важно обратить внимание на самую синтаксическую конструкцию. Программа состоит из множества синтаксических конструкций, вложенных друг в друга или следующих одна за другой. Нужно уметь видеть в тексте программы границы конструкций. Хороший программист вложенные конструкции выделяет отступом от левого края - чтобы было хорошо видно, что они вложенные. Окаймляющая инструкция разбита на части, находящиеся в разных строчках, но это единая инструкция, которая записывается так, и части которой нельзя пропускать или переставлять местами.

Число 4 здесь, если мы его оставим, фактически не приведёт нас к прогрессу. Единственный плюс от такого цикла будет в том, что не надо будет копировать много раз одно и то же. И это важный плюс конструкции. Вообще хороший программист стремится, чтобы в программе не было одинаковых частей, полученных копирование одного и то же куска кода во много мест.

Вместо константы - числа 4 - мы, конечно, можем использовать переменную. Например, n. В Ruby все переменные обязательно начинаются с маленькой буквы. (Про константы и переменные см. выше.) Однако если мы просто так напишем переменную n, наша программа не будет работать, потому что переменная будет пустой (в ней не будет числа). Чтобы получить число, можно использовать два действия:

Код: (Ruby)
x = gets
Специальная команда gets приостанавливает выполнение программы, и ждёт, что пользователь напечатает в консоли при помощи клавиатуры. Печатать он может что угодно до нажатия клавиши Enter. Как только он её нажимает, всё напечатанное становится результатом команды. И этот результат будет иметь тип текстовой строки. Если до gets написать переменную и равно, результат будет записан в переменную.

Чтобы из строки получить число, у объекта строки нужно вызвать специальную операцию to_i, которая попытается превратить строку в число. Если в строке действительно было напечатано число, операция успешно выполнится и выдаст в качестве результата число. Его-то мы и сможем использовать. Например:
Код: (Ruby)
n = "4".to_i
Теперь в переменной n записано число 4 (не строка).


simka, тебе осталось обобщить всё вышесказанное и представить на суд более продвинутую программу, способную застёгивать сколько хочешь пуговиц, если пользователь программы потрудится ввести с клавиатуры число, указывающее желательное для него количество пуговиц.

P.S. Перефразируя Ленина: пуговица неисчерпаема Улыбаюсь
« Последнее редактирование: 13-06-2012 20:01 от Dimka » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
simka
Постоялец

ru
Offline Offline
Пол: Женский

« Ответ #143 : 30-06-2012 05:18 » 

Код: (Ruby)
x = gets
n = "x".to_i
n.times do
  # puts "button up"
end

Как-то так или снова не в те дебри?
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #144 : 30-06-2012 06:48 » 

simka, направление верное, но код, конечно, неработающий.

Причём ты его не запускала. Если посмотришь темы начинающих, а особенно неотложку, ты там увидишь, что доминирующим шаблоном является: "Я запускаю, а оно не работает. Почему?" Ты же, похоже, и до этой положительной стадии не добралась. Иначе бы не спрашивала, правильно ли написанное тобою.

Ты фактически скомпоновала 3 кусочка из моих пояснений, но то были примеры. Твоя же цель - программа по застёгиванию пуговиц. И, как я говорил выше, критерий истины - это работающая программа. Если ты запустишь своё творение, ты не увидишь заветных надписей на экране. Дальше у тебя возникнет резонный вопрос "почему?". И вот в это-то драматический момент крушения надежд как раз и рождается в человеке программист, ибо человек начинает вдумываться в написанное, точно зная, что "дурак железный" оттого и дурак, что сам догадаться не может, и что какую-то ошибку допустил именно человек при написании кода.

Подсказка: проблемы в строчке 2 (см. выше разницу между константой и переменной) и в строчке 4 (см. синтаксис, что значит #).
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Страниц: 1 2 3 4 [5]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines