Closed jan-christiansen closed 1 year ago
Hier sind noch ein paar Beispiele aus den Laboraufgaben, um den Ansatz später zu evaluieren.
Im besten Fall würde die Regel für die Methoden containsHelp
und isNull
bessere Namen vorschlagen.
static <T> boolean containsHelp(final T current, final T value) {
return value == null && current == null || current != null && current.equals(value);
}
static <T> boolean isNull(T temp, T value) {
return temp != null && temp.equals(value) || temp == null && value == null;
}
Auch für die Methoden helpcountNodes
und add
sollte die Regel im besten Fall bessere Namen vorschlagen.
public int countNodes() {
return helpcountNodes(root);
}
public int helpcountNodes(final BinTreeNode root) {
if (root == null) {
return 0;
} else {
return 1 + helpcountNodes(root.right) + helpcountNodes(root.left);
}
}
private int count(final BinTreeNode check) {
if (check == null) {
return 0;
} else {
return 1 + count(check.left) + count(check.right);
}
}
private void add(final List<Integer> list, final BinTreeNode node) {
if (node != null) {
if (node.right != null) {
add(list, node.right);
}
list.add(0, node.value);
if (node.left != null) {
add(list, node.left);
}
}
}
Viele der Methodennamen in den Aufgaben sind vorgegeben. Für diese Namen sollte die Regel keine Alternativen vorschlagen. Daher muss es eine Whitelist geben, die angibt, welche Methodennamen gar nicht erst kontrolliert werden. Diese Whitelist ist insbesondere wichtig, da die Regel ansonsten für falsch implementierte Methoden neue Namen vorschlagen würde, obwohl die Implementierung einfach korrigiert werden sollte. Das führt vermutlich schnell zu Verwirrung.
Fragen: Umgang wenn Name in Vorschlägen vorkommt add(list, BinTreeNode) -> wird zu add Umbenennung der Methode, um Einfluss zu nehmen?
Problem(e) bei rekursiven Methoden
Varianten der Beispiel-Methoden in code2vec testen
code2seq
static <T> boolean containsHelp(final T current, final T value) {
return value == null && current == null || current != null && current.equals(value);
}
code2vec:
Original name: contains|help
(0.337449) predicted: ['equal']
(0.222097) predicted: ['eq']
(0.152269) predicted: ['are', 'equal']
(0.130073) predicted: ['is', 'equal']
(0.056747) predicted: ['equals']
(0.045972) predicted: ['safe', 'equals']
(0.027768) predicted: ['matches']
(0.013918) predicted: ['same', 'as']
(0.007310) predicted: ['is', 'current']
(0.006396) predicted: ['compare', 'values']
code2seq:
Original name: contains|help
Predicted: ['is', 'equal']
static <T> boolean isNull(T temp, T value) {
return temp != null && temp.equals(value) || temp == null && value == null;
}
code2vec:
Original name: is|null
(0.179465) predicted: ['safe', 'equals']
(0.169058) predicted: ['equals']
(0.147519) predicted: ['eq']
(0.137217) predicted: ['equal']
(0.106244) predicted: ['null', 'safe', 'equals']
(0.091403) predicted: ['are', 'equal']
(0.066828) predicted: ['is', 'equal']
(0.062435) predicted: ['same']
(0.022597) predicted: ['compare', 'values']
(0.017234) predicted: ['is', 'identical']
code2seq:
Original name: is|null
Predicted: ['equals']
public int helpcountNodes(final BinTreeNode root) {
if (root == null) {
return 0;
} else {
return 1 + helpcountNodes(root.right) + helpcountNodes(root.left);
}
}
code2vec:
Original name: helpcount|nodes
(0.189534) predicted: ['get', 'image', 'path']
(0.162416) predicted: ['get', 'descripcion', 'justificante']
(0.113696) predicted: ['get', 'waiting', 'consumer', 'count']
(0.087972) predicted: ['get', 'tipo', 'tramite']
(0.084806) predicted: ['has', 'native', 'allocation']
(0.084696) predicted: ['splay']
(0.077957) predicted: ['convert', 'id']
(0.074889) predicted: ['valid', 'type']
(0.070948) predicted: ['get', 'start', 'sequence', 'number']
(0.053086) predicted: ['uid']
code2seq:
Original name: helpcount|nodes
Predicted: ['nodes']
private void add(final List<Integer> list, final BinTreeNode node) {
if (node != null) {
if (node.right != null) {
add(list, node.right);
}
list.add(0, node.value);
if (node.left != null) {
add(list, node.left);
}
}
}
code2vec:
Original name: add
(0.722491) predicted: ['add']
(0.078461) predicted: ['add', 'all']
(0.052235) predicted: ['add', 'to', 'list']
(0.040259) predicted: ['add', 'int']
(0.034390) predicted: ['add', 'child', 'nodes']
(0.017696) predicted: ['add', 'objects']
(0.014537) predicted: ['add', 'if', 'not', 'null']
(0.013726) predicted: ['to', 'list']
(0.013132) predicted: ['populate', 'list']
(0.013072) predicted: ['append', 'list']
code2seq:
Original name: add
Predicted: ['add']
Momentan werden beide Netze folgendermaßen benutzt:
Ein Befehl lädt das Modell und versetzt es in den predict-Modus. Das laden des Models dauert etwa 40 Sekunden auf meinem Rechner. Das Ende des Ladens wird durch eine Ausgabe auf stdout angezeigt. Jetzt kann die Input.Java Datei im Hauptverzeichnis geändert werden und mit einem beliebigen Tastendruck in dem Terminal wird der Java-Code in dieser evaluiert. Die Auswertung des Codes dauert etwa eine Sekunde.
Das Ergebnis der Auswertung wird wieder in stdout geschrieben. Danach kann die Input.Java erneut verändert werden um den nächsten Code zu evaluieren.
Implementation der Regel momentan hier: #340
In diesem Issue soll einmal beispielhaft eine Regel implementiert werden, die mithilfe eines wahrscheinlichkeitsbasierten Ansatzes Vorschläge für die Verbesserung von Bezeichnern macht. Im konkreten Fall sollen Vorschläge für Methodennamen gemacht werden. Der Ansatz soll die Technik unter https://code2vec.org einsetzen. Dazu muss erst einmal erarbeitet werden, wie das trainierte neuronale Netz unter https://github.com/tech-srl/code2vec verwendet werden kann. Die Struktur der Regel ist ähnlich zur Regel, welche die Sprache eines Bezeichners überprüft. Mit einem Shell-Kommando wird für eine Methode das neuronale Netz ausgewertet und liefert Vorschläge inklusive Wahrscheinlichkeit des Vorschlages. Als Eingabe verlangt das neuronale Netz allerdings die Definition der Methode. Es muss also erarbeitet werden, welche Form dieses Argument genau haben muss.