Skip to content

Feedback#1

Open
github-classroom[bot] wants to merge 106 commits intofeedbackfrom
main
Open

Feedback#1
github-classroom[bot] wants to merge 106 commits intofeedbackfrom
main

Conversation

@github-classroom
Copy link
Contributor

@github-classroom github-classroom bot commented Mar 20, 2023

👋! GitHub Classroom created this pull request as a place for your teacher to leave feedback on your work. It will update automatically. Don’t close or merge this pull request, unless you’re instructed to do so by your teacher.
In this pull request, your teacher can leave comments and feedback on your code. Click the Subscribe button to be notified if that happens.
Click the Files changed or Commits tab to see all of the changes pushed to main since the assignment started. Your teacher can see this too.

Notes for teachers

Use this PR to leave feedback. Here are some tips:

  • Click the Files changed tab to see all of the changes pushed to main since the assignment started. To leave comments on specific lines of code, put your cursor over a line of code and click the blue + (plus sign). To learn more about comments, read “Commenting on a pull request”.
  • Click the Commits tab to see the commits pushed to main. Click a commit to see specific changes.
  • If you turned on autograding, then click the Checks tab to see the results.
  • This page is an overview. It shows commits, line comments, and general comments. You can leave a general comment below.
    For more information about this pull request, read “Leaving assignment feedback in GitHub”.

Subscribed: @raf-nr @vacmannnn @gladiuswq

github-classroom bot and others added 30 commits March 20, 2023 10:48
add: gradle init files, cbreated gradle application for project 'trees-9'
created abstract node, tree and bst pattern's
removed parent in node, changed type of rootNode
changed abstract tree to binary tree, implemented find
function and add in bst
deleting node.kt to split into separate files
Implemented BinarySearchTree, all nodes. Inited RBTree and AVLTree
Comment on lines +207 to +251
Column() {
Column(
Modifier.width(200.dp).height(260.dp).offset(25.dp, 10.dp),
verticalArrangement = Arrangement.Top,
horizontalAlignment = Alignment.Start,
) {
val fieldsWidth = 140
var key by remember { mutableStateOf("") }
OutlinedTextField(
modifier = Modifier
.width(fieldsWidth.dp)
.height(65.dp)
.padding(vertical = 5.dp),
value = key,
onValueChange = {
textMessage = mutableListOf("")
key = it
enteredKey = it
},
label = { Text("Enter key", textAlign = TextAlign.Center) }
)
var value by remember { mutableStateOf("") }
OutlinedTextField(
modifier = Modifier
.width(fieldsWidth.dp)
.height(65.dp)
.padding(vertical = 5.dp),
value = value,
onValueChange = {
value = it
enteredValue = it
},
label = { Text("Enter value", textAlign = TextAlign.Center) }
)
}
val text = textMessage.toString().slice(1 until textMessage.toString().length - 1)
Text(
text = text,
fontSize = 18.sp,
modifier = Modifier
.offset((10).dp, (-55).dp)
.width(150.dp),
textAlign = TextAlign.Center,
)
}
Copy link

@Artem-Rzhankoff Artem-Rzhankoff May 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

В BSTScreen.kt дублируется этот фрагмент. Вместо этого можно было бы использовать общий метод для сокращения количества кода и более быстрого фикса/рефакторинга

Comment on lines +17 to +20
import trees.BSTree
import trees.dataBases.BST.insertAllNodesToTree
import trees.dataBases.BST.removeFile
import trees.dataBases.BST.writeAllNodesToFile

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Unused import directive" (также в BSTScreen, RBScreen, nodeFunctions)

val x1 = getX(end).dp
val y1 = getY(end).dp

if (marker == true) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (marker == true) {
if (marker) {

Comment on lines +131 to +161
Button(
onClick = {
findMode = false
try {
textMessage = mutableListOf("")
tree.value.remove(enteredKey.toInt())
screenReload = true
} catch (_: NumberFormatException) {
textMessage = mutableListOf("Node with this key doesn't exist")
}
}) {
Text(
text = "Remove node",
modifier = Modifier.width(110.dp),
fontSize = 16.sp,
textAlign = TextAlign.Center
)
}
Button(
onClick = {
textMessage = mutableListOf("Write key that you are looking for")
findMode = !findMode
screenReload = true
}) {
Text(
text = "Find mode",
modifier = Modifier.width(110.dp),
fontSize = 16.sp,
textAlign = TextAlign.Center
)
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Дублирование (BSTScreen.kt 139-169), также можно было вынести в отдельный метод

fun AVLScreen(toMenu: () -> Unit) {
val db = SQLiteDB("./app/src/main/kotlin/trees/dataBases/AVL/base.db")
val tree = remember { mutableStateOf(AVLTree<Int, String>()) }
var textMessage by remember { mutableStateOf(mutableListOf<String>()) }

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
var textMessage by remember { mutableStateOf(mutableListOf<String>()) }
val textMessage = remember { mutableStateListOf<String>()}

Из документации

Comment on lines +98 to +117
var coordinate = Coordinate(850f, 0f)
var parent = AVLNode(0, "")
var value =
settingValue(enteredValue, coordinate.x + 50.0f, coordinate.y + .0f, 0, false)
var curNode = BSNode(enteredKey.toInt(), value)
tree.value.add(curNode.key, curNode.value)
if (tree.value.root?.key != enteredKey.toInt()) {
parent = getAVLParent(enteredKey.toInt(), tree.value.root!!)
coordinate = getCoordinate(parent.value)
println("${coordinate.x} ${coordinate.y}")
}
val point = findBracketPoint(value)
val offset = 85f
value = if (parent.left?.key == enteredKey.toInt()) {
settingValue(value, coordinate.x - offset, coordinate.y + offset, point, true)
} else {
settingValue(value, coordinate.x + offset, coordinate.y + offset, point, true)
}
curNode = BSNode(enteredKey.toInt(), value)
tree.value.add(curNode.key, curNode.value)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Этот фрагмент также можно вынести в отдельный метод, который будет принимать tree в качестве параметра

}
}
}
var dop = 0
Copy link

@Artem-Rzhankoff Artem-Rzhankoff May 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Совсем не очевидно, что обозначает переменная

Copy link
Collaborator

@TimPushkin TimPushkin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Общие комментарии:

  1. У вас явно два раздельных модуля: библиотека и приложение -- лучше было разделить их на два Gradle-проекта, иначе весь код перемешен.
  2. Есть неотвеченные и непофикшенные комментарии предыдущих ревьюеров, с которыми я согласен -- я их не повторял, но стоило бы их исправить.

Комментарии к библиотеке:

  1. Пользователю при поиске по дереву возвращается вершина, через интерфейс которой он может изменять внутреннюю структуру дерева, нарушая любые его инварианты -- нормальная инкапсуляция отсутствует. Нужно было создать для пользователя отдельный интерфейс вершины, через который нельзя было бы изменять структуру дерева.
  2. Есть повторяющийся код. Нужно было пользоваться возможностями ООП (такими как наследование) и переиспользовать уже реализованную функциональность.
  3. Стоило добавить документацию к публичным методам и/или хотя бы примеры работы с библиотекой в ридми.
  4. Тесты -- это нечто... Для начала, они просто не работают: в некоторых в функции проверки не передаются те деревья, что тестируются. Более того, самих тестов недостаточно, да и основная часть тех, что есть, построены полностью на рандоме, из-за чего непонятно, тестируются ли на самом деле все крайние случаи. Помимо всего этого, тесты AVL- и красно-черного деревьев -- просто копипаста тестов обычного дерева с точностью до вызова функции проверки. И последнее: нет тестов балансировки красно-черного дерева, зато зачем-то есть тесты балансировки обычного дерева (которое не балансирующееся) 🤯.

Комментарии к интерфейсу приложения:

  1. При нажатии на кнопки "Binary search tree" и "AVL tree" в главном меню приложение падает :'( Судя по сообщению, в обоих случаях не может найти файлы, пути к которым захардкожены в исходниках.
  2. При переходе между главным меню и редактором дерева размер окна сбрасывается, что неудобно
  3. На единственном экране редактора, что я смог открыть -- "Red-black tree" -- ни одна кнопка, кроме выхода обратно в меню, не работает, но об этом меня предупредили.

Комментарии к коду приложения:

  1. При билде появляются варнинги -- такого быть не должно.
  2. Непродуманная архитектура. По сути, нет никакого разделения наподобие MVC/MVP/MVVM или чего-то подобного, работа с деревьями находится прямо в UI.
  3. Нет разделения UI на элементы с их переиспользованием: каждый экран -- это огромная монолитная функция, причем, для каждого дерева -- почему-то своя.

Общее впечатление от работы плохое. Выглядит, будто делали в спешке и кое-как. Очень неаккуратный код, особенно в приложении, где ещё и архитектура по сути отсутствует. Само приложение в текущем состоянии не работает. В библиотеке пользователь может как хочет ломать внутреннюю структуру деревьев, тесты слабые.

with:
distribution: zulu
java-version: '17'
cache: gradle
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Для Gradle лучше использовать специальный официальный экшн -- у него лучше кэширование (и как бонус, можно чуть более компактно через него же Gradle-таски запускать)

run:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

На Винде у вас какой-то варнинг вылезает -- можно в Actions увидеть

README.md Outdated
Comment on lines 39 to 44
Test coverage by Intellej IDEA:
| Tree | Methods % | Lines % |
| ------------------- |:---:|:--:|
| Binary search tree | 100 | 96 |
| AVL tree | 100 | 98 |
| Reb-Black tree | 100 | 93 |
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Немного смущает, что оно не соответствует тому, что в CI высвечивается:
image

Видимо в CI статистика по всему коду, включая приложение, раз вы модули не разделили.

Но jacoco по соответствующим классам тоже чуть более скромные числа выдаёт:
image

В общем, такие штуки статически в ридми указывать не стоит: код поменяете, а здесь не обновите -- уже будет неправда. Если хочется, чтобы покрытие было видно в ридми, есть всякие генераторы бейджей, хотя и не уверен, что есть настолько подробные.

*/

rootProject.name = "trees-9"
include("app")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

У вас есть два явно раздельных компонента: библиотека и приложение -- их по-хорошему надо было разделить на два Gradle-проекта. Это уменьшило бы связность кода. Из очевидного для конкретно вашего случая, это позволило бы запускать таску по проверке test coverage только для библиотеки.

Comment on lines +24 to +26
testImplementation("org.junit.jupiter:junit-jupiter:5.8.1")
testImplementation("org.junit.jupiter:junit-jupiter:5.8.1")
testImplementation("org.junit.jupiter:junit-jupiter:5.8.1")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gradle с первого раза понимает :)

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AVLScreen(toMenu: () -> Unit) {
val db = SQLiteDB("./app/src/main/kotlin/trees/dataBases/AVL/base.db")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

А это, видимо, место, из-за которого падает экран AVL-дерева. Это видимо надо было спрашивать у пользователя, а не хардкодить. Да и вообще сначала дать дерево создать и сохранить, и только потом пытаться его загружать.


class SQLiteDB(private val path: String) : Closeable {
private val connection = DriverManager.getConnection("$DB_DRIVER:$path")
?: throw SQLException("Cannot connect to database")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Вроде бы эта ошибка нигде не отлавливается. То есть если вы пофиксите ваш код так, чтобы спрашивать путь у пользователя, то если он случайно ошибётся в пути, то всё приложение упадёт -- такого быть не должно. Ошибки нужно отлавливать и выдавать пользователю соответствующее понятное сообщение так, чтобы приложение при этом не падало.

}

fun open() {
connection.createStatement().also { statement ->
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Не понятно, зачем тут also -- лучше было просто сохранить в переменную и использовать её. Суть была бы та же, а вложенность бы уменьшилась. А ещё лучше использовать use, как вам уже ранее писали.

}

fun writeAllNodesToDB(node: AVLNode<Int, String>?, tree: AVLTree<Int, String>) {
val stack = mutableListOf(node?.key)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Уже писал в другом файле: используйте Stack из Java

import java.io.Closeable
import java.io.IOException

class Neo4jRepository: Closeable {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Пользуйтесь автоформатированием IDE:
Suggested change
class Neo4jRepository: Closeable {
class Neo4jRepository : Closeable {
  1. Для работы с Closable ресурсами (например, сессиями) используйте use -- вам не придется руками их закрывать, это обезопасит вас от утечек.
  2. У вас бросаются эксепшены -- убедитесь, что приложение будет их отлавливать и выдавать пользователю понятное сообщение так, чтобы само приложение при этом не падало.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants