Викторина - 4 варианта ответа, 30 секунд в первой фазе и 10 секунд во второй (можно поменять ответ)
Сопоставление стран и традиций
Игра по типу ЧтоГдеКогда надо ввести верный ответ (планирую засчитывать и по смыслу подходящие ответы). Квиз лучше запускается на компьютере, чем на телефоне. При желании можете добавить вопросы или в целом поменять какие-то структурные моменты.
[Код достаточно скопировать в блокнот и сохранить как html]
Скрытый текст
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8" />
<title>Новогодний квиз</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
/* --- Новогодний фон с градиентом --- */
background: linear-gradient(to bottom, #b3d9ff, #ffffff);
}
.hidden {
display: none;
}
.question-container {
margin: 20px 0;
padding: 10px;
border: 1px solid #ccc;
background-color: #fff;
}
.timer {
font-weight: bold;
color: red;
margin-bottom: 10px;
}
.correct {
background-color: #c8ffc8;
}
.incorrect {
background-color: #ffc8c8;
}
.match-container,
.short-answer-container {
margin: 20px 0;
padding: 10px;
border: 1px solid #ccc;
background-color: #fff;
}
.match-item {
margin-bottom: 10px;
}
.results {
margin: 20px 0;
padding: 10px;
border: 1px solid #ccc;
background-color: #fff;
}
h2, h3 {
margin-top: 0;
}
</style>
</head>
<body>
<h1>Новогодний квиз</h1>
<!-- *************************************
ЧАСТЬ 1. ВИКТОРИНА С ТАЙМЕРОМ
************************************* -->
<div id="quiz-section">
<h2>1. Викторина</h2>
<p>
Выберите один из предложенных вариантов ответа.
Каждому вопросу отводится
<strong>30 секунд в первой фазе</strong> и
<strong>10 секунд во второй фазе</strong> (можно изменить/внести свой ответ в любой из фаз).
</p>
<div id="quiz-container" class="question-container">
<!-- Вопросы будут появляться динамически через JavaScript -->
</div>
<div id="quiz-result" class="results hidden"></div>
</div>
<!-- *************************************
ЧАСТЬ 2. СОПОСТАВИТЬ СТРАНУ И ТРАДИЦИЮ
************************************* -->
<div id="match-section" class="hidden">
<h2>2. Сопоставьте страну и традицию празднования Нового года</h2>
<p>Выберите, к какой стране относится каждое описание традиции.</p>
<div id="match-container" class="match-container">
<!-- Сопоставление стран и традиций будет сгенерировано через JavaScript -->
</div>
<button id="check-match">Проверить</button>
<div id="match-result" class="results hidden"></div>
</div>
<!-- *************************************
ЧАСТЬ 3. КОРОТКИЕ ОТВЕТЫ
************************************* -->
<div id="short-answer-section" class="hidden">
<h2>3. Ответьте на вопросы</h2>
<!-- Вопрос 1 -->
<div class="short-answer-container">
<p><strong>Вопрос 1:</strong> Как называется главный символ Нового года, который впервые появился в СССР в 1935 году, чтобы заменить рождественские традиции?</p>
<input type="text" id="answer1" placeholder="Ваш ответ..." style="width: 60%;" />
</div>
<!-- Вопрос 2 -->
<div class="short-answer-container">
<p><strong>Вопрос 2:</strong> В 1977 году группа советских исследователей встретила Новый год, устроив праздничный ужин и собрав импровизированную "ёлку" из подручных материалов. В чём заключалась уникальность этого события?</p>
<input type="text" id="answer2" placeholder="Ваш ответ..." style="width: 60%;" />
</div>
<!-- Вопрос 3 -->
<div class="short-answer-container">
<p><strong>Вопрос 3:</strong> В 2024-м наступил год ... Дракона, предыдущий аналогичный год был в 1964-м. В китайской традиции ... считается элементом роста, успеха и развития. Энергия ... Дракона по традиции окрашена в зеленый цвет. Каким «противоречивым» прилагательным обозначен 2024 год согласно китайской традиции?</p>
<input type="text" id="answer3" placeholder="Ваш ответ..." style="width: 60%;" />
</div>
<!-- Вопрос 4 -->
<div class="short-answer-container">
<p><strong>Вопрос 4:</strong> Человек однажды пережил три откровения: о тепле, что было, о холоде, что окружает, и о безмолвии, что ждёт. Это изменило его навсегда. Кто этот человек?</p>
<input type="text" id="answer4" placeholder="Ваш ответ..." style="width: 60%;" />
</div>
<!-- Вопрос 5 -->
<div class="short-answer-container">
<p><strong>Вопрос 5:</strong> Великий японский поэт Мацуо Басё написал на Новый год хокку:<br/>
<em>Год за годом<br/>
Обезьяна носит<br/>
Маску обезьяны</em><br/>
Он сам называл это хокку «неудачным» и сожалел о нём. Какое свойство (черту) человека хотел подчеркнуть Басё этим стихотворением?
</p>
<input type="text" id="answer5" placeholder="Ваш ответ..." style="width: 60%;" />
</div>
<button id="check-short-answers">Проверить</button>
<div id="short-answer-result" class="results hidden"></div>
</div>
<script>
// ===================== ДАННЫЕ ДЛЯ ВИКТОРИНЫ (ЧАСТЬ 1) =====================
const quiz_data = [
{
question: "Какой праздник может праздноваться позже остальных?",
options: ["Новый год", "Рождество", "Ханука", "Кванза"],
answer: "Рождество"
},
{
question: "Какая страна подарила нам стеклянные ёлочные игрушки?",
options: ["Германия", "Франция", "Россия", "Китай"],
answer: "Германия"
},
{
question: "Сколько месяцев в году имеют 31 день?",
options: ["5", "6", "7", "8"],
answer: "7"
},
{
question: "Какое животное, по славянским поверьям, нельзя было пускать в дом на Новый год, так как это приносило неудачу?",
options: ["Мышь", "Кошка", "Собака", "Лошадь"],
answer: "Кошка"
},
{
question: "Что символизирует ёлка в новогоднем декоре?",
options: ["Радость", "Здоровье", "Вечную жизнь", "Удачу"],
answer: "Вечную жизнь"
},
{
question: "В каком году началась традиция наряжать ёлку (впервые документально зафиксированно)?",
options: ["1605", "1705", "1805", "1905"],
answer: "1605"
},
{
question: "Какой город в России считается \"столицей новогодних ёлок\"?",
options: ["Москва", "Йошкар-Ола", "Санкт-Петербург", "Пермь"],
answer: "Йошкар-Ола"
},
{
question: "Какая страна в Азии празднует Новый год не зимой, а весной?",
options: ["Индия", "Китай", "Япония", "Вьетнам"],
answer: "Индия"
},
{
question: "Какой предмет изменил героя и стал причиной всех бед в известной новогодней сказке?",
options: ["Старый манжетный камень", "Волшебная кукла", "Зеркало с магическим заклинанием", "Волшебные часы"],
answer: "Зеркало с магическим заклинанием"
},
{
question: "Какое государство первым в мире официально признало 1 января началом нового года?",
options: ["Древняя Греция", "Вавилон", "Древний Рим", "Египет"],
answer: "Древний Рим"
}
];
// ===================== ДАННЫЕ ДЛЯ СОПОСТАВЛЕНИЯ (ЧАСТЬ 2) =====================
const match_data = [
{
country: "Япония",
tradition: "В полночь слушают 108 ударов колокола в буддийских храмах..."
},
{
country: "Италия",
tradition: "В некоторых регионах принято выбрасывать из окон старую мебель и вещи..."
},
{
country: "Испания",
tradition: "В полночь необходимо съесть 12 виноградин — по одной с каждым ударом часов..."
},
{
country: "Китай",
tradition: "Празднования включают шествия с драконами, танцы львов и запуск фейерверков..."
},
{
country: "Греция",
tradition: "Пекут пирог «василопита» с монеткой внутри..."
},
{
country: "Дания",
tradition: "Разбивают старую посуду о двери друзей, чем больше осколков, тем лучше..."
},
{
country: "Филиппины",
tradition: "В новогоднюю ночь ценят круглые предметы. Люди украшают дома круглыми фруктами и даже надевают одежду в горошек..."
},
{
country: "Шотландия",
tradition: "Первый человек, вошедший в дом (First-Footing), должен принести уголь, хлеб или виски..."
},
{
country: "Бразилия",
tradition: "Люди надевают белую одежду, а на пляжах запускают цветы в океан в честь богини Иеманжи..."
},
{
country: "Южная Корея",
tradition: "Кланяются старшим, чтобы получить благословение, готовят суп из рисовых лепёшек (токкук)..."
}
];
// Собираем все страны в один массив (для выпадающих списков)
let allCountries = match_data.map(item => item.country);
// Функция для перемешивания массива (алгоритм Фишера–Йетса)
function shuffle(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
// ===================== ЛОГИКА ВИКТОРИНЫ (ЧАСТЬ 1) =====================
// 1-я фаза: 30 секунд на вопрос
// 2-я фаза: 10 секунд на вопрос
let phase1Time = 30;
let phase2Time = 10;
// Текущее состояние викторины
let quizPhase = 1; // 1 или 2
let currentQuestionIndex = 0; // индекс вопроса
let userAnswers = new Array(quiz_data.length).fill(null);
let timerInterval = null;
const quizContainer = document.getElementById("quiz-container");
const quizResult = document.getElementById("quiz-result");
// Запуск викторины
startQuiz();
function startQuiz() {
quizPhase = 1;
currentQuestionIndex = 0;
showNextQuestion();
}
function showNextQuestion() {
// Проверяем, не вышли ли за пределы массива
if (currentQuestionIndex >= quiz_data.length) {
// Если прошли все вопросы в фазе 1 — переходим ко 2-й фазе
if (quizPhase === 1) {
quizPhase = 2;
currentQuestionIndex = 0;
showNextQuestion();
return;
} else {
// Если уже фаза 2 — значит закончили
finishQuiz();
return;
}
}
// Отображаем вопрос
renderQuizQuestion(currentQuestionIndex);
// Запускаем таймер (зависит от фазы)
const timeForThisPhase = (quizPhase === 1) ? phase1Time : phase2Time;
startPhaseTimer(timeForThisPhase);
}
function renderQuizQuestion(index) {
const questionObj = quiz_data[index];
let questionNumber = index + 1;
// Генерируем html для вариантов ответа
// Если уже есть ответ пользователя, помечаем radio как checked
let optionsHtml = questionObj.options.map((opt, i) => {
let checked = (userAnswers[index] === opt) ? "checked" : "";
return `
<div>
<input type="radio" name="quiz_option" id="option_${i}" value="${opt}" ${checked}>
<label for="option_${i}">${opt}</label>
</div>
`;
}).join("");
quizContainer.innerHTML = `
<div class="timer" id="timer"></div>
<h3>Вопрос ${questionNumber} из ${quiz_data.length} (фаза ${quizPhase})</h3>
<p><strong>${questionObj.question}</strong></p>
${optionsHtml}
`;
}
function startPhaseTimer(duration) {
let timeLeft = duration;
const timerEl = document.getElementById("timer");
timerEl.textContent = `Осталось времени: ${timeLeft} сек. (фаза ${quizPhase})`;
if (timerInterval) clearInterval(timerInterval);
timerInterval = setInterval(() => {
timeLeft--;
timerEl.textContent = `Осталось времени: ${timeLeft} сек. (фаза ${quizPhase})`;
if (timeLeft <= 0) {
clearInterval(timerInterval);
lockAnswerAndMoveNext();
}
}, 1000);
}
function lockAnswerAndMoveNext() {
// Сохраняем выбор пользователя
const selected = document.querySelector('input[name="quiz_option"]:checked');
if (selected) {
userAnswers[currentQuestionIndex] = selected.value;
}
// Переходим к следующему вопросу
currentQuestionIndex++;
showNextQuestion();
}
function finishQuiz() {
// Очищаем контейнер и выводим результаты
quizContainer.innerHTML = "";
quizResult.classList.remove("hidden");
// Подсчёт правильных ответов
let correctCount = 0;
let detailHtml = "<h3>Результаты викторины:</h3>";
detailHtml += "<ol>";
quiz_data.forEach((q, i) => {
const userAns = userAnswers[i];
const isCorrect = (userAns === q.answer);
if (isCorrect) correctCount++;
detailHtml += `
<li>
<strong>${q.question}</strong><br/>
Ваш ответ: <span style="color:${isCorrect ? 'green' : 'red'}">${userAns || "нет ответа"}</span><br/>
Правильный ответ: <span style="color:green">${q.answer}</span>
</li>
`;
});
detailHtml += "</ol>";
detailHtml += `<p><strong>Правильных ответов: ${correctCount} из ${quiz_data.length}</strong></p>`;
quizResult.innerHTML = detailHtml;
// Показываем 2-ю часть
document.getElementById("match-section").classList.remove("hidden");
}
// ===================== ЛОГИКА СОПОСТАВЛЕНИЯ (ЧАСТЬ 2) =====================
const matchContainer = document.getElementById("match-container");
const matchResult = document.getElementById("match-result");
const checkMatchBtn = document.getElementById("check-match");
// Перед рендером перемешиваем список стран, чтобы варианты были в случайном порядке
shuffle(allCountries);
function renderMatchItems() {
match_data.forEach((item, index) => {
// Сформируем <option> из массива allCountries (уже перемешанного)
let optionsHtml = `<option value="">(Выберите страну)</option>`;
allCountries.forEach(country => {
optionsHtml += `<option value="${country}">${country}</option>`;
});
const div = document.createElement("div");
div.className = "match-item";
div.innerHTML = `
<p><strong>Традиция ${index + 1}:</strong> ${item.tradition}</p>
<select id="match_select_${index}">
${optionsHtml}
</select>
`;
matchContainer.appendChild(div);
});
}
renderMatchItems();
checkMatchBtn.addEventListener("click", () => {
let correctMatchCount = 0;
match_data.forEach((item, index) => {
const selectEl = document.getElementById(`match_select_${index}`);
const userCountry = selectEl.value;
if (userCountry === item.country) {
selectEl.classList.add("correct");
selectEl.classList.remove("incorrect");
correctMatchCount++;
} else {
selectEl.classList.remove("correct");
selectEl.classList.add("incorrect");
}
});
matchResult.classList.remove("hidden");
matchResult.innerHTML = `<p>Вы сопоставили верно: <strong>${correctMatchCount}</strong> из <strong>${match_data.length}</strong>.</p>`;
// Показываем 3-ю часть
document.getElementById("short-answer-section").classList.remove("hidden");
});
// ===================== ЛОГИКА КОРОТКИХ ОТВЕТОВ (ЧАСТЬ 3) =====================
const checkShortAnswersBtn = document.getElementById("check-short-answers");
const shortAnswerResult = document.getElementById("short-answer-result");
checkShortAnswersBtn.addEventListener("click", () => {
// Теперь 5 вопросов, каждый по 2 балла → максимум 10.
let score = 0;
// Считываем ответы пользователя (trim + toLowerCase):
const ans1 = document.getElementById("answer1").value.trim().toLowerCase();
const ans2 = document.getElementById("answer2").value.trim().toLowerCase();
const ans3 = document.getElementById("answer3").value.trim().toLowerCase();
const ans4 = document.getElementById("answer4").value.trim().toLowerCase();
const ans5 = document.getElementById("answer5").value.trim().toLowerCase();
// Упростим букву 'ё' → 'е'
function fixYo(str) {
return str.replace(/ё/g, "е");
}
// --- Варианты правильных ответов на каждый вопрос ---
// 1) Новогодняя ёлка / елка
const q1_variants = ["новогодняя елка", "новогодняя ёлка"];
// 2) «космос / в космосе» (оставляем простую проверку includes)
const q2_variants = ["космос", "в космосе"];
// 3) «деревянный / деревяный»
const q3_variants = ["деревянный", "деревяный"];
// 4) «скрудж / эбенезер» (из рождественской истории)
const q4_variants = ["скрудж", "эбенезер"];
// 5) «неизменность»
const q5_variants = ["неизменност"];
// достаточно "неизменност" для includes() — чтобы засчитывать "неизменность" целиком
// -----------------------------
// Проверка (includes)
let isQ1Correct = q1_variants.some(v => fixYo(ans1).includes(fixYo(v)));
let isQ2Correct = q2_variants.some(v => fixYo(ans2).includes(fixYo(v)));
let isQ3Correct = q3_variants.some(v => fixYo(ans3).includes(fixYo(v)));
let isQ4Correct = q4_variants.some(v => fixYo(ans4).includes(fixYo(v)));
let isQ5Correct = q5_variants.some(v => fixYo(ans5).includes(fixYo(v)));
if (isQ1Correct) score += 2;
if (isQ2Correct) score += 2;
if (isQ3Correct) score += 2;
if (isQ4Correct) score += 2;
if (isQ5Correct) score += 2;
// Подсветка
markAnswer("answer1", isQ1Correct);
markAnswer("answer2", isQ2Correct);
markAnswer("answer3", isQ3Correct);
markAnswer("answer4", isQ4Correct);
markAnswer("answer5", isQ5Correct);
// Сформируем текст результата
shortAnswerResult.classList.remove("hidden");
let resultText = `<p><strong>Ваш результат за короткие ответы:</strong> ${score} баллов (из 10).</p>`;
resultText += "<ul>";
// Вопрос 1:
resultText += `<li><strong>Вопрос 1:</strong> «Новогодняя ёлка/елка»
<br/>${isQ1Correct ? "Верно" : "Неверно"}.
<br/><em>Пояснение:</em> Рождественские традиции в СССР заменили на «новогоднюю елку».</li>`;
// Вопрос 2:
resultText += `<li><strong>Вопрос 2:</strong> «Космос / В космосе»
<br/>${isQ2Correct ? "Верно" : "Неверно"}.
<br/><em>Пояснение:</em> Это был первый Новый год, который люди отмечали в космосе.</li>`;
// Вопрос 3:
resultText += `<li><strong>Вопрос 3:</strong> «Деревянный / Деревяный»
<br/>${isQ3Correct ? "Верно" : "Неверно"}.
<br/><em>Пояснение:</em> В китайской традиции 2024 год — «Деревянный», отсюда его своеобразная «противоречивость».</li>`;
// Вопрос 4 (Скрудж):
resultText += `<li><strong>Вопрос 4:</strong> «Скрудж» (Эбенезер)
<br/>${isQ4Correct ? "Верно" : "Неверно"}.
<br/><em>Пояснение:</em> Это герой Рождественской истории (Чарльза Диккенса), который встретил трех духов и навсегда изменился.</li>`;
// Вопрос 5 (Неизменность):
resultText += `<li><strong>Вопрос 5:</strong> «Неизменность»
<br/>${isQ5Correct ? "Верно" : "Неверно"}.
<br/><em>Пояснение:</em> С приближением нового года приходит обезьяна маваси. Даже если вы наденете на эту обезьяну новую маску обезьяны, она все равно останется обезьяной. Содержимое вообще не меняется. То же самое касается и людей. Ничего не изменится, даже если в новом году мы покажем его заново.
По мнению Басё, несмотря на попытки создать новое, люди часто повторяют одни и те же ошибки,
оставаясь неизменными, словно «обезьяна в маске обезьяны».</li>`;
resultText += "</ul>";
shortAnswerResult.innerHTML = resultText;
});
function markAnswer(elemId, isCorrect) {
let el = document.getElementById(elemId);
el.classList.remove("correct", "incorrect");
el.classList.add(isCorrect ? "correct" : "incorrect");
}
</script>
</body>
</html>
Против реверс-инженера недолго продержится. Но если руководство поставит эту задачу, кому то еще, думаю они через неделю махнут рукой. А как противостоять реверс-инженеру надо писать статью "Сложная защита скрипта без выноса логики на сервер")
Спасибо за комментарий. В статье я хотел рассказать о доступных инструментах именно на питоне. Перевести в сишный код хорошая идея, но единственное я не знаю как себя буду вести библиотеки вроде Селениум, при такой операции.
Я сомневаюсь, что "unpack pyarmor" будет достаточно, что сломать последнюю версию pyarmor. То что сломать можно да, но это нетривиальная задача и в большинстве компаний (особенно в малом и среднем бизнесе) маловероятно, что такой сотрудник найдется.
Согласен с вами, использовал неудачную формулировку, изначально хотел написать бизнес-логику, но показалось тавтология будет. Так, безусловно, конфиденциальную информацию, в прямом смысле слова, мы в приложение не добавляем.
[1] "Spain vs Germany -> Prediction: Home Win"
[1] "Portugal vs France -> Prediction: Away Win"
[1] "Netherlands vs Turkey -> Prediction: Away Win"
[1] "England vs Switzerland -> Prediction: Home Win"
Результаты 1/8:
6/8 прошло. Довольно низкие кэфы были на фаворитов, Турция вывела в плюс (1.17, 1.07, 1.40, 1.16, 1.18, 2.80)
Квиз состоит из 3 частей:
Викторина - 4 варианта ответа, 30 секунд в первой фазе и 10 секунд во второй (можно поменять ответ)
Сопоставление стран и традиций
Игра по типу ЧтоГдеКогда надо ввести верный ответ (планирую засчитывать и по смыслу подходящие ответы). Квиз лучше запускается на компьютере, чем на телефоне. При желании можете добавить вопросы или в целом поменять какие-то структурные моменты.
[Код достаточно скопировать в блокнот и сохранить как html]
Скрытый текст
Прям не работа, а мечта)
Запаковать заново экзешник, изменить зависимости при необходимости
Против реверс-инженера недолго продержится. Но если руководство поставит эту задачу, кому то еще, думаю они через неделю махнут рукой. А как противостоять реверс-инженеру надо писать статью "Сложная защита скрипта без выноса логики на сервер")
Спасибо за комментарий. В статье я хотел рассказать о доступных инструментах именно на питоне. Перевести в сишный код хорошая идея, но единственное я не знаю как себя буду вести библиотеки вроде Селениум, при такой операции.
Я сомневаюсь, что "unpack pyarmor" будет достаточно, что сломать последнюю версию pyarmor. То что сломать можно да, но это нетривиальная задача и в большинстве компаний (особенно в малом и среднем бизнесе) маловероятно, что такой сотрудник найдется.
Согласен с вами, использовал неудачную формулировку, изначально хотел написать бизнес-логику, но показалось тавтология будет. Так, безусловно, конфиденциальную информацию, в прямом смысле слова, мы в приложение не добавляем.
ChatGPT o1-preview
Думал на протяжении 7 секунд
Чтобы решить эту задачу, давайте определим две переменные:
G = количество девушек
P = количество свиней
Шаг 1: Поймем анатомию
Девушки: у каждой девушки 2 ноги и 2 соска.
Свиньи: у каждой свиньи 4 ноги. У свиней обычно 14 сосков (так как у них несколько пар сосков).
Шаг 2: Составим уравнения на основе общих количеств
Уравнение для общего количества ног:
2G+4P=106
Уравнение для общего количества сосков:
2G+14P=336
Шаг 3: Решим систему уравнений
Вычтем первое уравнение из второго, чтобы исключить G:
(2G+14P)−(2G+4P)=336−106
(14P−4P)=230
10P=230
P=230/10
P=23
Теперь подставим P=23P = 23P=23 обратно в первое уравнение, чтобы найти G:
2G+4(23)=106
2G+92=106
2G=106−92
2G=14
G=14/2
G=7
Шаг 4: Проверим решение
Общее количество ног: 2(7)+4(23)=14+92=106
Общее количество сосков: 2(7)+14(23)=14+322=336
Оба значения соответствуют заданным числам.
Ответ: 7
ChatGPT 4o - не смог решить задачу, получил 28.75 и заявил, что задача требует пересмотра логики
Прогноз 1/2:
[1] "Spain vs France -> Prediction: Home Win" [1] "Netherlands vs England -> Prediction: Away Win"
Результаты 1/4:
3/4 прошло (1.87, 1.67, 1.58)
Прогноз 1/4:
[1] "Spain vs Germany -> Prediction: Home Win" [1] "Portugal vs France -> Prediction: Away Win" [1] "Netherlands vs Turkey -> Prediction: Away Win" [1] "England vs Switzerland -> Prediction: Home Win"
Результаты 1/8:
6/8 прошло. Довольно низкие кэфы были на фаворитов, Турция вывела в плюс (1.17, 1.07, 1.40, 1.16, 1.18, 2.80)
-380$ (гр.) + 78$ (1/8) = -302$
Индекс безопасности - чем выше тем лучше, меньше преступлений.
Индекс загрязнения - чем ниже тем лучше, меньше уровень загрязнения.
Добавлю здесь)