Prints out a list of options and returns the array key of the chosen value.

@param  string $question Question to ask
@param  array  $options  Numeric array of options to choose from
@return int
519891
protected function select(string $question, array $options): int
	{
		return (new Select($this->input, $this->output))->ask($question, $options);
	}
271426
private function serializeSolutions(GridQuestion $gridQuestion, array $options = [])
    {
        $solutions = [];

        foreach ($gridQuestion->getCells()->toArray() as $cell) {
            $cellChoices = $cell->getChoices()->toArray();

            if (!empty($cellChoices)) {
                $solutionData = [
                    'cellId' => $cell->getUuid(),
                    'answers' => [],
                ];

                foreach ($cellChoices as $choice) {
                    $solutionData['answers'][] = $this->cellChoiceSerializer->serialize($choice, $options);
                }
                $solutions[] = $solutionData;
            }
        }

        return $solutions;
    }
916736
protected function askChoice($question, $options, $default = NULL) {
    return $this->doAsk(new ChoiceQuestion($this->formatQuestion($question),
      $options, $default));
  }
590812
public static function int(&$value, $options = ['max'=>null, 'min'=>null, 'default'=>null])
    {
        $value = (int)$value;
        self::processNum($value, $options);
        return $value;
    }
358058
public function serialize(SelectionQuestion $selectionQuestion, array $options = [])
    {
        $serialized = [
            'text' => $selectionQuestion->getText(),
            'mode' => $selectionQuestion->getMode(),
        ];

        if ($selectionQuestion->getPenalty()) {
            $serialized['penalty'] = $selectionQuestion->getPenalty();
        }

        if ($selectionQuestion->getTries()) {
            $serialized['tries'] = $selectionQuestion->getTries();
        }

        switch ($selectionQuestion->getMode()) {
           case SelectionQuestion::MODE_FIND:
               $serialized['tries'] = $selectionQuestion->getTries();
              break;
           case SelectionQuestion::MODE_SELECT:
               $serialized['selections'] = $this->serializeSelections($selectionQuestion);
              break;
           case SelectionQuestion::MODE_HIGHLIGHT:
               $serialized['selections'] = $this->serializeSelections($selectionQuestion);
               $serialized['colors'] = $this->serializeColors($selectionQuestion);
              break;
        }

        if (in_array(Transfer::INCLUDE_SOLUTIONS, $options)) {
            $serialized['solutions'] = $this->serializeSolutions($selectionQuestion);
        }

        return $serialized;
    }
745667
public function validateAfterSchema($question, array $options = [])
    {
        $errors = [];

        if (empty($question['content'])) {
            // No blank content
            $errors[] = [
                'path' => '/content',
                'message' => 'Question content can not be empty',
            ];
        }

        if (!isset($question['score'])) {
            // No question with no score
            // this is not in the schema because this will become optional when exercise without scores will be implemented
            $errors[] = [
                'path' => '/score',
                'message' => 'Question score is required',
            ];
        }

        if (in_array(Validation::REQUIRE_SOLUTIONS, $options) && !isset($question['solutions'])) {
            // No question without solutions
            $errors[] = [
                'path' => '/solutions',
                'message' => 'Question requires a "solutions" property',
            ];
        }

        if (!$this->itemDefinitions->has($question['type'])) {
            $errors[] = [
                'path' => '/type',
                'message' => 'Unknown question type "'.$question['type'].'"',
            ];
        }

        // Validate hints
        if (isset($question['hints'])) {
            array_map(function ($hint) use (&$errors, $options) {
                $errors = array_merge($errors, $this->hintValidator->validateAfterSchema($hint, $options));
            }, $question['hints']);
        }

        // Validate objects
        if (isset($question['objects'])) {
            array_map(function ($object) use (&$errors, $options) {
                $errors = array_merge($errors, $this->contentValidator->validateAfterSchema($object, $options));
            }, $question['objects']);
        }

        // Validates specific data of the question type
        if (empty($errors)) {
            // Forward to the correct definition
            $definition = $this->itemDefinitions->get($question['type']);

            $errors = array_merge(
                $errors,
                $definition->validateQuestion($question, array_merge($options, [Validation::NO_SCHEMA]))
            );
        }

        return $errors;
    }
517822
public function getQuestionConfirm(
        $question,
        $default = 'y',
        array $options = array('y', 'n'),
        $required = true
    ) {
        return $this->getQuestion($question, $default, $options, $required);
    }
963002
public static function options($key, $value = ':get:')
    {
        if (is_array($key)) {
            foreach ($key as $k => $v) {
                static::$options($k, $v);
            }

            return;
        }

        if ($value === ':get:') {
            return isset(static::$options[$key]) ? static::$options[$key] : null;
        }

        static::$options[$key] = $value;
    }
813075
static public function formatQueryOptions($options=null)
    {
        if (!isset($options)) {
            return [];
        }
        
        if (is_scalar($options)) {
            $options = ['where' => [$options]];
        } elseif (isset($options['where'])) {
            $options['where'] = (array) $options['where'];
        } else {
            $isWhere = true;
            foreach ($options as $k => $v) {
                if (is_numeric($k)) {
                    unset($options[$k]);
                    $options['where'][] = $v;
                } elseif (in_array($k, ['distinct', 'fields', 'from', 'table', 'order', 'pagesize', 'page', 'result_key'])) {
                    $isWhere = false;
                    break;
                }
            }
            if ($isWhere) {
                $options = ['where' => $options];
            } else {
                $options['where'] = [];
            }
        }
        
        return $options;
    }
1368479
protected function checkOptionsInt(array $options, array $keys)
    {
        foreach ($keys as $intOption) {
            if (isset($options[$intOption]) && !is_int($options[$intOption])) {
                throw new InvalidOptionException($this, $options);
            }
        }
    }
136107
public function optionOrAsk($option, $question, $default = null)
    {
        $value = $this->input->getOption($option);
        if ($value === null || Str::likeEmpty($value)) {
            $value = $this->ask($question, $default);
        }

        return $value;
    }
348321
private function serializeMetadata(Item $question, array $options = [])
    {
        $metadata = ['protectQuestion' => $question->getProtectUpdate()];

        $creator = $question->getCreator();

        if (!empty($creator)) {
            $metadata['creator'] = $this->userSerializer->serialize($creator, $options);
            // TODO : remove me. for retro compatibility with old schema
            $metadata['authors'] = [$this->userSerializer->serialize($creator, $options)];
        }

        if ($question->getDateCreate()) {
            $metadata['created'] = DateNormalizer::normalize($question->getDateCreate());
        }

        if ($question->getDateModify()) {
            $metadata['updated'] = DateNormalizer::normalize($question->getDateModify());
        }

        if (in_array(Transfer::INCLUDE_ADMIN_META, $options)) {
            /** @var ExerciseRepository $exerciseRepo */
            $exerciseRepo = $this->om->getRepository(Exercise::class);

            // Gets exercises that use this item
            $exercises = $exerciseRepo->findByQuestion($question);
            $metadata['usedBy'] = array_map(function (Exercise $exercise) {
                return $exercise->getUuid();
            }, $exercises);

            // Gets users who have access to this item
            $users = $this->om->getRepository(Shared::class)->findBy(['question' => $question]);
            $metadata['sharedWith'] = array_map(function (Shared $sharedQuestion) use ($options) {
                $shared = [
                    'adminRights' => $sharedQuestion->hasAdminRights(),
                    'user' => $this->userSerializer->serialize($sharedQuestion->getUser(), $options),
                ];

                return $shared;
            }, $users);
        }

        return $metadata;
    }
621674
protected function get_correct_answers($question) {
        $arrayofchoices = $this->get_array_of_choices($question);
        $arrayofplaceholdeers = $this->get_array_of_placeholders($question);

        $correctplayers = array();
        foreach ($arrayofplaceholdeers as $ph) {
            foreach ($arrayofchoices as $key => $choice) {
                if ($key + 1 == $ph) {
                    $correctplayers[] = $choice;
                }
            }
        }
        return $correctplayers;
    }
1248891
public function getPk($options = '')
    {
        if (!empty($this->pk)) {
            $pk = $this->pk;
        } else {
            $pk = $this->getTableInfo(is_array($options) ? $options['table'] : $options, 'pk');
        }
        return $pk;
    }
139007
private function serializeSolutions(BooleanQuestion $question)
    {
        return array_map(function (BooleanChoice $choice) {
            $solutionData = [
                'id' => $choice->getUuid(),
                'score' => $choice->getScore(),
            ];

            if ($choice->getFeedback()) {
                $solutionData['feedback'] = $choice->getFeedback();
            }

            return $solutionData;
        }, $question->getChoices()->toArray());
    }
1171413
public function serialize(PairQuestion $pairQuestion, array $options = [])
    {
        $serialized = [
            'random' => $pairQuestion->getShuffle(),
            'penalty' => $pairQuestion->getPenalty(),
            'rows' => $pairQuestion->getRows()->filter(function (GridRow $row) {
                return 0 < $row->getScore();
            })->count(),  // The grid only contains expected answers
        ];

        $items = $this->serializeItems($pairQuestion, $options);

        if (in_array(Transfer::SHUFFLE_ANSWERS, $options)) {
            shuffle($items); // shuffle the pool of items
        }

        $serialized['items'] = $items;

        if (in_array(Transfer::INCLUDE_SOLUTIONS, $options)) {
            $serialized['solutions'] = $this->serializeSolutions($pairQuestion);
        }

        return $serialized;
    }
315375
public function in($question = '')
	{
		$question ? : $this->question;

		if ($this->win)
		{
			if ($question)
			{
				$this->output->out()->out($question, false);
			}

			$value = rtrim(shell_exec($this->hiddenExe));

			$this->output->out();

			return $value;
		}

		// Using stty help us test this class.
		elseif ($this->findStty())
		{
			if ($question)
			{
				$this->output->out()->out($question, false);
			}

			// Get stty setting
			$setting = shell_exec('stty -g');

			shell_exec('stty -echo');

			$value = fread($this->inputStream, 8192);

			shell_exec(sprintf('stty %s', $setting));

			if ($value === false)
			{
				throw new \RuntimeException('Cannot get input value.');
			}

			$this->output->out();

			return rtrim($value);
		}

		// For linux & Unix system
		else
		{
			// Find shell.
			$shell = $this->findShell();

			if (!$shell)
			{
				throw new \RuntimeException("Can't invoke shell");
			}

			$this->output->out();

			// Using read to write password
			$read = sprintf('read -s -p "%s" mypassword && echo $mypassword', $question);

			// Here we use bash to handle this command.
			$command = sprintf("/usr/bin/env bash -c '%s'", $read);

			$value = rtrim(shell_exec($command));

			$this->output->out();

			return $value;
		}
	}