All streams
Search
Write a publication
Pull to refresh
7
0

Пользователь, Аналитик, IT-энтузиаст

Send message

Квиз состоит из 3 частей:

  1. Викторина - 4 варианта ответа, 30 секунд в первой фазе и 10 секунд во второй (можно поменять ответ)

  2. Сопоставление стран и традиций

  3. Игра по типу ЧтоГдеКогда надо ввести верный ответ (планирую засчитывать и по смыслу подходящие ответы). Квиз лучше запускается на компьютере, чем на телефоне. При желании можете добавить вопросы или в целом поменять какие-то структурные моменты.

    [Код достаточно скопировать в блокнот и сохранить как 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. То что сломать можно да, но это нетривиальная задача и в большинстве компаний (особенно в малом и среднем бизнесе) маловероятно, что такой сотрудник найдется.

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

ChatGPT o1-preview

Думал на протяжении 7 секунд

Чтобы решить эту задачу, давайте определим две переменные:

  • G = количество девушек

  • P = количество свиней

Шаг 1: Поймем анатомию

  • Девушки: у каждой девушки 2 ноги и 2 соска.

  • Свиньи: у каждой свиньи 4 ноги. У свиней обычно 14 сосков (так как у них несколько пар сосков).

Шаг 2: Составим уравнения на основе общих количеств

  1. Уравнение для общего количества ног:

    2G+4P=106

  2. Уравнение для общего количества сосков:

    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$

Индекс безопасности - чем выше тем лучше, меньше преступлений.

Индекс загрязнения - чем ниже тем лучше, меньше уровень загрязнения.

Добавлю здесь)

Information

Rating
Does not participate
Registered
Activity

Specialization

Data Analyst
R
Python
SQL
Tableau