## 3 Program Text Vectorization  
The unsupervised learning algorithms used in the DTA analytics module require program texts to be preliminarily transformed into vectors. Code to vector transformation is also required during classifier training and prediction-making [35], so in this section we briefly describe vectorization of program texts submitted by students. Several approaches to source code to vector transformation exist [35; 36], but the DTA analytics module uses its own vectorization algorithm, which respects the specifics of the generators of unique programming exercises [6; 10]. The source code vectorization problem might be reduced to the development of a mapping \(f:P\rightarrow\mathbb{R}^{m}\), where \(P\) denotes the set of program texts, and \(m\) denotes the dimensionality of the target vector space. The vectorization algorithm used in DTA first constructs an AST \(a_{i}\) for every program text \(p_{i}\in P\) using the AST module from the Python standard library. Then, nodes belonging to the set _(Import, Load, Store, alias, arguments, arg, Module, keyword)_ are removed from the AST. The resulting AST \(a_{i}\) of a program that solves one of the automatically generated tasks of type 6 (see Table 1, see Figure 1a) using a pattern matching-based approach is shown in Figure 2. The AST visualization was obtained using the graphviz library [37]. Assuming the fact that the unique task generators used in DTA are based on probabilistic grammars [6; 10], the AST \(a_{i}\) of each program text \(p_{i}\in P\) is then transformed into a Markov chain state transition graph \(g_{i}\). A Markov chain is a model describing a sequence of events \(E_{0},E_{1},\ldots,E_{n}\), where the probability of event \(E_{n}\), \(n\geq 1\), only depends on the state attained on the previous event \(E_{n-1}\)[38]. In a Markov chain graph, vertices represent types of AST nodes, edges represent transitions between AST nodes, and weights of edges denote transition probabilities. While constructing a Markov chain state transition graph \(g_{i}\) for  
Figure 2: AST of a program that solves one of the automatically generated tasks of type 6 (see Table 1, see Figure 1a) using a pattern matching-based approach, after applying AST transformations during program text vectorization in DTA. every AST \(a_{i}\) of each program text \(p_{i}\in P\), a number of AST node replacements listed in Table 2 are performed depending on task type. The examples of Markov chain state transition graphs obtained for programs that employ different approaches to solve different automatically generated tasks of type 6 (see Table 1, see Figure 1a) are shown in Figure 3.  
While different program texts may contain different node types, the set \(H\) containing all different AST node types that occur in Markov chains in a particular dataset is preliminarily constructed. All weighted adjacency matrices are constructed based on the \(H\) set, and every weighted adjacency matrix belongs to \(\mathbb{R}^{|H|\times|H|}\). The probabilities of transitions among node types that do not exist in a particular program text \(p_{i}\) but exist in other program texts are set to zeros in the resulting weighted adjacency matrix. In the final step, the weighted adjacency matrices of Markov chain state transition graphs are reshaped to vectors belonging to \(\mathbb{R}^{m}\), where \(m=|H|^{2}\). This way the mapping \(f:P\rightarrow\mathbb{R}^{m}\) is implemented, where \(P\) denotes the set of program texts, and \(m\) is the dimensionality of a vector. Algorithm 1 summarizes the vectorization process of a dataset containing source codes of programs solving automatically generated tasks of a particular type (see Table 1).