## 4 Results  
Table 2 shows the amount of cloned GitHub repositories and the amount of parsed Python modules for each category. Additionally, Table 3 showcases the results of training data aggregations. Figure 3 shows us that there is a significant difference in the complexity of source code within the categories observed in our research. There are three reasons for this. The first reason lies in the fact that scientific programming, covered by AI and Data Science categories, tends to result in Interactive Python notebooks, which hold the entire application within a single file. The second reason is due to the problem's complexity. Educational programming problems, covered by object-oriented programming and problem-solving categories, tend to solve an oddly specific problem, and the code is usually held within a single module for self-sustainability. The third reason takes root in software development practices, which can be observed within the Python project. In software development, there is a tendency to keep things simple and separate concerns, which means that there are usually more Python modules found in such source codes. Our SOM, configured as specified in Table 1 produced both distributional and differential data, representing the distribution of programming concepts and the differences between them, respectively. A visualization of those data can be seen on Figure 4.  
Figure 5 depicts that one SOM neuron will be activated for 98% of the AST nodes when our test codes consist of just one concept. This shows that SOMs consider such code to be trivial in complexity and ultimately very similar. The following two outputs come from SOM, after their weight vector has been expressed with Python's abstract syntax:  
* Module Assign Expr Call Constant Name Load Store \begin{table}
\begin{tabular}{c c c} \hline \hline
**Code Category** & **Number of Repositories** & **Number of Python Modules** \\ \hline Python project & 2 & 153 \\ \hline Problem solving & 2 & 113 \\ \hline Object-oriented programming & 7 & 297 \\ \hline AI & 7 & 2306 \\ \hline Data science & 2 & 179 \\ \hline Python tutorial & 5 & 834 \\ \hline \hline \end{tabular}
\end{table} 
Table 2: Quantity of collected data. \begin{table}
\begin{tabular}{l l l l l l l l l} \hline \hline  & \multicolumn{3}{c}{**Tree Depth**} & \multicolumn{6}{c}{**Node Count**} \\ \hline
**Category** & **Min** & **Max** & **Mean** & **Median** & **Min** & **Max** & **Mean** & **Median** \\ \hline AI & 1 & 119 & 10.532 & 11.0 & 1 & 17307 & 919.138 & 534.5 \\ \hline Data Science & 1 & 22 & 8.849 & 10.0 & 1 & 8893 & 787.888 & 581.0 \\ \hline OOP & 1 & 22 & 9.252 & 9.0 & 1 & 253,206 & 1613.66 & 124.0 \\ \hline Problem solving & 6 & 18 & 11.283 & 12.0 & 15 & 690 & 187.752 & 152.0 \\ \hline Python project & 1 & 17 & 8.071 & 9.0 & 1 & 5594 & 169.104 & 46.0 \\ \hline Python tutorial & 1 & 22 & 9.486 & 9.0 & 1 & 8343 & 497.285 & 227.0 \\ \hline \hline \end{tabular}
\end{table} 
Table 3: Results of training data aggregations. It can be observed that we successfully trained the SOM to make a distinction between the following two programming concepts:  
* Using a variable to store a value
* Reusing the variable to utilize the stored value  
Figure 6 shows us that training resulted in a relatively high quantization error (2.025) and a relatively low topographic error (0.2). The following source codes provide a solution to the same problem: calculating and printing the sum of list elements. Figure 3: Visualization of training data aggregations. Figure 4: Code distribution within the SOM based on categories. Figure 5: SOM activation when facing individual AST nodes. Based on the source code provided in Appendix A, Table 4 shows us that the SOM acts as a sieve of sorts, with the code structure being a distinguishable feature that impacts which of the SOM's neurons are the best fit to represent the code. Only one neuron can be the winner, and that decision is based on the conceptual density of the source code in our example.