Skip to content

Feedback#1

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

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

Conversation

@github-classroom
Copy link
Contributor

@github-classroom github-classroom bot commented Mar 14, 2024

👋! 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: @homka122 @Demon32123 @far1yg

Copy link

@qrutyy qrutyy left a comment

Choose a reason for hiding this comment

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

Очень приятный код RB, с минимальными недочетами) (поэтому ниже пару вопросов по архе). Единственное - хотелось бы получить конечную версию либы не в последний день (кхм вечер), но код не потребовал излишних усилий для разбора, и на вряд ли потребует этого от пользователя))).

import tree.node.RBTreeNode

class RBTree<K : Comparable<K>, V> : SearchTree<K, V, RBTreeNode<K, V>> {
constructor() : super()
Copy link

Choose a reason for hiding this comment

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

Не очень понятно, зачем конструктор не принимающий аргументов)

Copy link
Contributor

Choose a reason for hiding this comment

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

Чтобы создать пустое дерево без нодов

Comment on lines +1 to +5
import tree.node.BinaryTreeNode

fun main() {
println("Hello world!")
} No newline at end of file
Copy link

Choose a reason for hiding this comment

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

Не очень понятен смысл main файла в библиотеке. Все-таки это не фреймворк, и скорее всего будет использоваться в составе другого "приложения". Хотя кейсы разные бывают.
P.S. в ревью присутствуют некоторые вопросы по архитектуре, надеюсь это не станет проблемой. Код показался мне довольно хорошим, поэтому решил задать их здесь.

Copy link
Contributor

Choose a reason for hiding this comment

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

это должно было добавлено в .gitignore и использоваться для личных нужд, спасибо

import tree.node.RBTreeColor
import tree.node.RBTreeNode

class RBTree<K : Comparable<K>, V> : SearchTree<K, V, RBTreeNode<K, V>> {
Copy link

Choose a reason for hiding this comment

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

Прошу пояснить, про момент использования size. В данной реализации не увидел взаимодействия с данным параметром. 🐈

Copy link
Contributor

Choose a reason for hiding this comment

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

Вся ответственность за работу с size лежит на абстрактном классе и не принуждает разработчиков этим заниматься или думать об этом

более того — size это закрытое для изменения поле внутри класса и мы не можем его меня

это сделано осознанно

Copy link

Choose a reason for hiding this comment

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

Насколько size полезен для пользователя?

Copy link
Contributor

Choose a reason for hiding this comment

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

польза size в принципе довольно понятна — информация о том, сколько у нас пар Ключ/Значений

пользователь не может менять size, только читать

а в чем вопрос?

Copy link

Choose a reason for hiding this comment

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

Вопрос был только в полезности) Как доп. фича - понятно)

Comment on lines +1 to +5
package tree.node

enum class RBTreeColor {
BLACK, RED
} No newline at end of file
Copy link

Choose a reason for hiding this comment

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

В чем смысл выносить данный класс за пределы RBTreeNode?

Copy link
Contributor

Choose a reason for hiding this comment

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

так красивее

Copy link

Choose a reason for hiding this comment

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

О вкусах не поспоришь( 😭
Но я за размещение данного класса в пределах класса ноды, все-таки это состояние ноды данного класса)

Choose a reason for hiding this comment

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

Мне не нравится, что оно лежит в папочке с именем node. Этож не нода(

import org.junit.jupiter.api.Nested
import kotlin.random.Random

class RBTreeTest {
Copy link

Choose a reason for hiding this comment

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

В некоторых случаях стоит проверять цвета. Условно в маленьких деревьях большую роль будет играть цвет, а не положение нод (в том смысле, что оно вариативно + вполне очевидно), поэтому данный метод будет не лишним.

Copy link
Contributor

Choose a reason for hiding this comment

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

Только сейчас, видимо, понял о чем речь

Наша библиотека подразумевает, что пользователь не знает о такой абстракции, как нода, цвет и прочие элементы деревьев

Поэтому у нас нет инструментария для проверки цвета нодов без какого-либо лишнего пробрасывания этих скрытых элементов наружу

Следовательно и unit тестирование у нас происходит сугобо на публичных методах и результате их работы, лишь ссылаясь в названиях тестов на то, что мы на самом деле проверяем под капотом

@suvorovrain
Copy link

не поставлю тебе звездочек за попрошайничество

@homka122
Copy link
Contributor

homka122 commented Apr 7, 2024

@suvorovrain оболтус

@ItIsMrLaG
Copy link

ItIsMrLaG commented Apr 11, 2024

Короче, чистенько, не очень много кода. Есть недочеты, хотя по большей части good.

Вывод: мне нрав, довольно прямолинейно.

-_-
Ток чет я не понял, почему вас 2 контребьютора, а не 3
-_-

Copy link

@ItIsMrLaG ItIsMrLaG left a comment

Choose a reason for hiding this comment

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

См. сверху)

/**
* Returns the pair with next ascending key
*/
fun successor(key: K): Pair<K?, V?> {

Choose a reason for hiding this comment

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

Насколько имеют смысл кейсы: Pair(null, null), Pair(null, Any()), Pair(Any(), null)? Если я правильно понял, то два последних не имеют ни какого смысла. А Pair(null, null) можно было бы упростить до null. Таким образом, у всей функции можно было бы поменять возвращаемый тип на Pair<K, V>?.

Согласен, что придирка, но раз вы вытащили этот метод в API, то у него должен быть понятный интерфейс взаимодействия (на мой взгляд).
Либо я не очень понял что-то, так что вы можете поменять мое мнение)))

Choose a reason for hiding this comment

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

У меня кста такой вопрос ко всем вашим публичным методам, которые возвращают тип Pair<K?, V?>.

Comment on lines 15 to 23
bst = BSTree()
bst.set(5, "A")
bst.set(8, "A")
bst.set(6, "A")
bst.set(1, "A")
bst.set(2, "A")
bst.set(4, "A")
bst.set(3, "A")
bst.set(10, "A")

Choose a reason for hiding this comment

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

У вас же вроде для такого есть красивый конструктор (точно есть, я его в RBTreeTest видел...), в чем мотивация так дублировать код?)))

val entities = arrayOf(
Pair(35, "A"),
Pair(21, "A"),
Pair(25, "A"),

Choose a reason for hiding this comment

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

А чего тут Pair(), а не to... ? Ладно, ладно, дальше ревью без фигни будет, обещаю)

Comment on lines +91 to +112
fun `set one key on empty tree`() {
val data = arrayOf(1 to "Homka")
setTest(data)
}

@Test
fun `set second key as right child`() {
val data = arrayOf(1 to "Homka", 2 to "Dima")
setTest(data)
}

@Test
fun `set second key as left child`() {
val data = arrayOf(2 to "Homka", 1 to "Dima")
setTest(data)
}

@Test
fun `set third key as left child`() {
val data = arrayOf(2 to "Homka", 3 to "Dima", 1 to "Nastya")
setTest(data)
}

Choose a reason for hiding this comment

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

Хорошо, подробно, красиво названо, но можно иначе:

    private fun checkSize(size: Long,errMsg: String, rbt: RBTree<Int, String> = this.rbt) {
        // Любая ваша проверка
        assertEquals(size, rbt.size, message = errMsg)
    }
    
    @ParameterizedTest(name = "Something")
    @MethodSource("arrProvider")
    fun runner(data: Array<Pair<Int, String>>, errMsg: String) {
         rbt.set(data)
         checkSize(data.size.toLong(), errMsg)
    }

    companion object {
        @JvmStatic
        fun arrProvider(): Stream<Arguments> {
            return Stream.of(
                    Arguments.of(arrayOf(1 to "Homka"), "set one key on empty tree"),
                    Arguments.of(arrayOf(1 to "Homka", 2 to "Dima"), "set second key as right child"), 
                    Arguments.of(arrayOf(2 to "Homka", 1 to "Dima"), "set second key as left child"), 
                    Arguments.of(arrayOf(2 to "Homka", 3 to "Dima", 1 to "Nastya"), "set third key as left child"), 
            )
        }
    }

Имхо, так меньше повторяющегося кода + добавление новых тестов -- нечто ну очень быстрое. Возможно все 14 тестов этого класса можно было бы так переписать)
Хотя не спорю, что текущий метод тоже good

Comment on lines +100 to +107
assertEquals(Pair(2, "A"), bst.successor(1))
assertEquals(Pair(3, "A"), bst.successor(2))
assertEquals(Pair(4, "A"), bst.successor(3))
assertEquals(Pair(5, "A"), bst.successor(4))
assertEquals(Pair(6, "A"), bst.successor(5))
assertEquals(Pair(8, "A"), bst.successor(6))
assertEquals(Pair(10, "A"), bst.successor(8))
assertEquals(Pair(null, null), bst.successor(10))

Choose a reason for hiding this comment

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

Ну для такой красоты существуют @ParameterizedTest + @CsvSource:

    @ParameterizedTest
    @CsvSource(
        "2, A, 1",
        "3, A, 2",
        "4, A, 3",
        "5, A, 4",
        "6, A, 5",
        "8, A, 6",
    )
    fun `successor() test with existed keys`(k: Int, v: String, kf: Int) {
        assertEquals(Pair(k, v), bst.successor(kf))
    }

Мне так больше нравится)))

}
}

private fun getBalance(node: AVLTreeNode<K, V>): Int {

Choose a reason for hiding this comment

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

Набор вопросиков и рекомендаций от меня:

  1. А чего именно такое название, или разность в высотах -- это баланс называется? Я просто немного не в контексте, так что реально любопытно.
  2. Можно было бы написать короче, используя всю МоЩь островного языка:
private fun getBalance(node: AVLTreeNode<K, V>) = height(node.left) - height(node.right)
  1. У вас эта функция в одном месте используется (+ она оч маленькая). По моему субъективному мнению, такие вспомогательные функции лучше писать через замыкания(вложенные функции) в том месте, где они используются.

Comment on lines +1 to +5
package tree.node

enum class RBTreeColor {
BLACK, RED
} No newline at end of file

Choose a reason for hiding this comment

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

Мне не нравится, что оно лежит в папочке с именем node. Этож не нода(

run: ./gradlew build

- name: Launch tests
run: ./gradlew :lib:test

Choose a reason for hiding this comment

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

Покрытие бы посчитать где-нибудь, как-нибудь... (или у вас есть где-то спрятанное и это я слепец -_-)


import tree.node.BinaryTreeNode

abstract class SearchTree<K : Comparable<K>, V, Node : BinaryTreeNode<K, V, Node>>() {

Choose a reason for hiding this comment

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

А почему у вас тип SearchTree параметризуется BinaryTreeNode, а не SearchTreeNode. Тут надо бы как-то унифицировать, а то у вас в Search используется Binary, при этом в проекте есть BinarySearch (BS) :)

@@ -0,0 +1,293 @@
package tree

import tree.node.BinaryTreeNode

Choose a reason for hiding this comment

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

Подумал, что ноды, можно было бы сделать data классами. Но это так, на вкус и цвет фломастеры разные)

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.

7 participants