Skip to content

Feedback#1

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

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

Conversation

@github-classroom
Copy link
Contributor

@github-classroom github-classroom bot commented Apr 23, 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: @kar1mgh @spisladqo @qrutyy

github-classroom bot and others added 30 commits April 23, 2024 16:37
…ds and method implementations

Change graph to abstract class from interface. Add adjacencyMap and edges properties. Add deleteVertex and deleteEdge methods. Add implementation for addVertex, getVertices, getEdges methods.
… for them

Fix undirected and directed, weighted and unweighted graphs, add addEdge method implementation for them. Add new line at the end of all files
Add adding newly created edge to edges set in all graphs. Add visibility modifiers to abstract graph's properties. Change deleteVertex method's return value to vertex.
+ set the default value of weight to 0 in unweighted graphs
Due to different implementations of 'deleteEdge' method, it cant be defined in abstract as common, therefore, added its implementation in 'Undirected' & 'Directed' graph classess
Remove weight field from edge interface and unweighted edges, add it only to weighted edges. implement not implemented parent class method addEdge without weight parameter in weighted graphs, where weight is set to default value.
+ add return of a new vertex in addVertex method
Add model of 4 types of graphs for app
* chore: add ktfmt plugin to gradle

* style: apply ktfmt formatting

* feat: add pre-commit hook script

* fix: ktfmtCheckMain gradle task dependency
* refactor: change Edge from interface to abstract class

* fix: add edge generic type to abstract graph class

fix of a problem that methods return wrong edge type

* fix: abstract edge class initialization in inheritors after change from interface

* refactor: add wrap layer classes for more convenient usage
* feat: implement Dijkstra's shortest path algo

* fix: add path reconstruction

* fix: change methods name to distinguish the algorithms
* feat: implement Kosaraju's SCC algo

* fix: edit return value of SCC

* fix: switch stack type from mutable-list to array-deque

* refactor: apply formatter, remove redundant parenthesis
* fix: change vertex id type from ULong to Int

* feat: implement Kruskal's MST algorithm
* feat: add class for graph creation

* fix: upload draft implementations of new methods

* feat: implement 'add edges' and 'vertices'

* feat: throw 'graphType' parameter for FAQ

* feat: call representation after 'add' operations

* fix: add border dependency on 'scaleFactor'

* feat: create rough force-directed layout

* feat: add vertex ID display

* feat: modify some buttons + apply layout after changes

* feat: write draft t-FDP layout algo

* refactor: formatter + some small syntax changes

* fix: resolve conflicts after rebase

* fix: rename 'showId' variable, resolve issue with edges directions

* fix: change edge layer

* fix: remove debug lines

* fix: correct connection between UI and graphVM

* fix: add 'updateRequired' for graph update handle

* feat: handle 'updateRequired' + implement 'add Edge'

* refactor: apply plugin, add glitter

* refactor: move tab handler to a separate file

* feat: add zoom control buttons

* refactor: clean up the MainScreen file

* feat: handle resize after zoom

* feat: add id display and zoom handle

* refactor: remove unnecessary scale factors

* feat: improve scale handling, add borders for scale rate

* refactor: add new lines at the end, remove init

* refactor: remove commented lines
spisladqo and others added 15 commits May 24, 2024 17:35
* test: implement tests for key vertices finding algorithm

* refactor: apply same code style to tests
* fix: resolve merge conflict

* refactor: formatter + some small syntax changes

* feat: change question mark icon from pdf to svg format

* feat: change color of FAQ, make it more smooth

* feat: change FAQ text color to black

---------

Co-authored-by: qruty <64466788+qrutyy@users.noreply.github.com>
* fix: delete maxX and maxY from vertex view model

* refactor: delete redundant parameters and comments

* fix: delete extra parameters from function invocation
* test: change test for checking if graph didn't change

* fix(findCycles): copying of graph
* build: add new dependencies for int. tests

* test: implement first integration test

* feat: add getter for edge's direction type

* refactor: move graphs to a separate package in module

* feat: add test-tags

* fix: add tag for 'not hoverable' FAQ

* refactor: edit test name
* fix: small typo

* fix: correct graph types picked by user, change default types

* feat: add text field for graph name, save and load buttons

* feat: add base dialog windows which can be dismissed

* feat: introduce more variables

* feat: add dropdown menu for database choosing

* feat: add button and dialog to choose file when json is chosen
* feat: move constants to a separate file

* fix: make 'getWeightMap' return mutable map

* refactor: rename 'CreateGraphVM' class, edit 'addEdge'

* refactor: resolve TODO's

* fix: edit name of radius variable
* feat: add louvain clustering algorithm implementation by jetbrains-research

* feat: add class for running Louvain algorithm

* test: add tests for clustering

* chore: add license for used source code
* refactor: correct packages

* fix: remove erase data variable

* feat: implement DB creation and saving

* feat: add draft UI for file-control tab

* feat: implement general function to display error windows

* feat: set up the process of graph import, MSVM-VM-SQL connection

* feat: implement dialog window for graph import

* feat: implement DB handling. TOFIX: import

* feat: add auxiliary queries for SQLite

* fix: remove coroutines and launch ef., due to composable conflict

* refactor: remove redundant lines, cleared up a little

* fix: edit layout coefficients

* feat: add draft SQLite DB

* fix: display the FAQ and zoom

* test: enhance app with integration test draft #46

* build: add new dependencies for int. tests

* test: implement first integration test

* feat: add getter for edge's direction type

* refactor: move graphs to a separate package in module

* feat: add test-tags

* fix: add tag for 'not hoverable' FAQ

* refactor: edit test name

* feat: add basic file control tab fields and buttons #48

* fix: small typo

* fix: correct graph types picked by user, change default types

* feat: add text field for graph name, save and load buttons

* feat: add base dialog windows which can be dismissed

* feat: introduce more variables

* feat: add dropdown menu for database choosing

* feat: add button and dialog to choose file when json is chosen

* refactor: clean up code, resolve some TODO's #49

* feat: move constants to a separate file

* fix: make 'getWeightMap' return mutable map

* refactor: rename 'CreateGraphVM' class, edit 'addEdge'

* refactor: resolve TODO's

* fix: edit name of radius variable

* feat: add error message handle

* fix: edit button title, change ui layout

* feat: add SQLite save+import integration into UI

* fix: update queries, due to error with id

* feat: add graph name update and deletion

* fix: remove line, that ban MainScreen update

* feat: handle EditDB window

* feat: implement EditDB window

* refactor: correct dimensions and indices

* build: remove vulnerable dependencies

---------

Co-authored-by: Daniel Vlasenco <vlasenko.daniil26@gmail.com>
…e tab #51

* refactor: move key vertices finder algorithm to separate class

* refactor: move SCC and cycles find algorithms to separate classes

* refactor: move min spanning tree and bridges finder algorithms to separate classes

* refactor: move find shortest pat algorithms to separate class

* test: move algorithm tests to separate classes, add test cases for finding shortest path

+ make internal Dijkstra and Ford-Bellman private

* refactor: move graph tests to new graphs package

* refactor: change text in general tab buttons

* feat: add algorithm choosing in analyze tab

* feat: add drafts for algorithms UI
* feat: implement DB creation and saving

* feat: add draft UI for file-control tab

* feat: implement general function to display error windows

* feat: set up the process of graph import, MSVM-VM-SQL connection

* feat: add auxiliary queries for SQLite

* fix: remove coroutines and launch ef., due to composable conflict

* refactor: remove redundant lines, cleared up a little

* test: enhance app with integration test draft #46

* build: add new dependencies for int. tests

* test: implement first integration test

* feat: add getter for edge's direction type

* refactor: move graphs to a separate package in module

* feat: add test-tags

* fix: add tag for 'not hoverable' FAQ

* refactor: edit test name

* feat: add basic file control tab fields and buttons #48

* fix: small typo

* fix: correct graph types picked by user, change default types

* feat: add text field for graph name, save and load buttons

* feat: add base dialog windows which can be dismissed

* feat: introduce more variables

* feat: add dropdown menu for database choosing

* feat: add button and dialog to choose file when json is chosen

* refactor: clean up code, resolve some TODO's #49

* feat: move constants to a separate file

* fix: make 'getWeightMap' return mutable map

* refactor: rename 'CreateGraphVM' class, edit 'addEdge'

* refactor: resolve TODO's

* fix: edit name of radius variable

* feat: add error message handle

* fix: edit button title, change ui layout

* feat: add FFT implementation

Made by jnalon. Provide it with GPL-3.0 License

* fix: add 'apply layout' call after some changes

* feat: implement randomize method

* feat: implement T-FDP layout + FFT optimization

* fix: remove some unused lines

* fix: increase grid partition

* fix: remove unnecessary update

* fix: clean FFT, change coefficients

* feat: add SQLite db, with test graphs

---------

Co-authored-by: Daniel Vlasenco <vlasenko.daniil26@gmail.com>
* docs(readme): add project description

* docs(readme): add general tab screenshot

* docs(redame): corrct grammatical error
* feat: add UI for finding cycles and shortest path, make algorithms available only to corresponding graphs

* feat: add draft of UI for running layout

* feat: add methods that run algorithms in graphVM

+ update import graph dialog window

* feat: add methods that visualize algorithms

* feat: make algorithms runnable from UI
* feat: make gradle cleaner

* feat: add vertex and edge saving to neo4j

* feat: add function to save graph with name to neo4j

* feat: add function to clear graph from neo4j, use it in save function

* feat: add graph import by name from neo4j

* feat: move loaded graph initialization to another function

* refactor: remove unneeded exception throw

* fix: correct imports

* fix: first added vertex containing empty data

* fix: no more crash when entering empty id of vertex to connect with

* feat: remove independent id's and class generic from Neo4jRepository class

* feat: add message when graph was or was not saved to neo4j

* fix: bug with fake login into neo4j

* fix: error window appearing only once at a lifetime

* feat: add neo4j repo handler object to operate with repository

* fix: bug with making graph names empty just before save, load or edit

* feat: add neo4j load dialog window

* feat: remove all neo4j-related stuff from MainScreenVM
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.

Hi, I'm an (almost) former SE student who was asked to review and grade your code. Since the whole project uses English I'll also stick to that tradition.

I was told that your deadline was 23:59 May 29 but I see several significant commits made afterwards. I started my review on commit ff30eef, so this is the state I will be grading you for (that commit was actually made several hours past the deadline already).

General comments:

  • Code style is pretty decent but it could have been better. Pay attention to your IDE (IntelliJ IDEA is recommended for Kotlin): there is a lot of warnings (unused variables, code duplication, unrecommended use of Kotlin's features...), you can even see some of them in your CI.
  • There are problems with architecture. On higher level you chose to use MVVM but the layers are mixed it your code: there are pieces of UI in model, view model's logic in UI. You also sometimes violate abstraction and encapsulation principles of OOP, especially in UI-related code (e.g. a lot of properties and methods that could have been private). Code duplication is also a huge problem: there are quite a few classes, tests and even whole files that duplicate each other symbol by symbol.
  • UI looks cute but it could use some refactoring: split huge functions onto separate elements and reuse them to get rid of code duplication, remove unused variables, replace strings with enums, make better use of Compose's features
  • Would be nice to see more documentation: in README (what algorithms exactly are used, how the IO formats look internally), in code (links to articles/papers describing the algorithms with their pseudo-code), in UI (what is an "SCC", how key vertices are defined)
  • Great commit messages and PR descriptions 👏

In the comments below I use "💡" for comments/suggestions and "❗️" for more critical issues.

}
}

fun main() = application {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Issues I've found while using the app (some are just UX-related wishes):

  • ❗️ When the app starts, if I press "Import" then don't select anything and press "Import" again I get java.sql.SQLException: Graph with ID 0 not found. in the terminal and end up with a blank screen with no way to do anything, the only way from there is to restart the app
  • 💡 After opening a graph there is no way to return to the main menu except to close the app
  • 💡 When the window is resized the GUI gets stretched for a few seconds before coming back to normal
  • 💡 If the window is resized to the smallest size possible the left menus are cropped (especially noticeable on "Analyze" and "Save & Load" tabs), it would help if they were vertically scrollable
  • 💡 It would be nice to have bigger graph as examples, a few hundred nodes at least. When I was doing this task 3 years ago we had a requirement to support full graphs with up to 10000 nodes (you don't have this requirement)
  • "General" tab:
    • 💡 When creating a vertex I need to input some data to be stored in it but there seems to be no way to view that data anywhere in the app
    • 💡 If a vertex ID is too long (even two digits long) it is not possible to see the whole ID in the GUI, it gets cropped on the vertex borders
    • When I add a vertex the app asks me to input a second vertex for the first one to be connected to it:
      • 💡 Is there no way to create a stand-alone vertex? I actually check what will happen if I manually add such vertices in the SQLite database and it seems to be displayed correctly.
      • 💡 Even if I select "Integer" as the data to be stored I can input arbitrary strings like "asdasdsa" and they are accepted
      • ❗️ If there already exist some vertices then I'm asked to input an ID of the second vertex. If I don't input anything and press "Connect" I get java.lang.NumberFormatException: For input string: "" and the app crashes
    • 💡 When adding an edge if one of the vertices doesn't exist the related error message will only appear for the first time and if the same situation happens again it just won't appear until the tab is reopened
      • 💡 Actually, the same seems to happen with all such messages, e.g. in "Analyze" tab too
    • 💡 There is no way to specify the edge weight in a weighted graph
  • "Analyze" tab:
    • ❗️ For the layout algorithm, the buttons don't seem to work, nothing happens when I press them. 💡 And what do each of the sliders represent? Some meaningful names would really help.
    • 💡 The algorithm for finding key vertices gives strange results for your graph named "test_graph", I cannot really understand how the vertices it chooses can be defined as the key vertices in any meaningful way. It would be nice to have some documentation in README or in the app itself explaining what exactly the algorithm is supposed to find.
    • ❗️ The algorithm for finding SCCs crashes the app with java.lang.ArrayIndexOutOfBoundsException: Only 15 colors supported on "test_graph"
    • 💡 There should be two algorithms for finding graphs implemented: Dijkstra's and Bellman-Ford's, but in the UI it's just "Find shortest path" — it would be nice to know when each of them is used
  • "Save & Load" tab:
    • SQLite:
      • 💡 Just as in the main menu, if I press "Load" then don't select anything and press "Import" I get an exception in the terminal (though the app doesn't crash)
      • ❗️ Loading a graph doesn't work: I can select a graph but it is not imported and after that pressing "Load" again does nothing until I reopen the tab (this is probably the same problem as with the error messages appearing only once)
      • 💡 For some reason, "test_graph" has vertex type "Integer" in the database but it is imported (from the main menu) as having type "String", at the same time graph "hahahahahha" has type "Int" but is saved as having type "Integer" — to sum up, data types are not treated correctly
    • ❗️ Support for Neo4j and JSON is not implemented
    • 💡 It would be nice if positions and colors of vertices were also saved and restored — this was actually a requirement when I was doing this task (but for you it is not)

Ultimately, the UI looks cute but there are quite a few bugs, vertex data seems to be broken (is not used anywhere, data type is not checked), saving/loading only works for SQLite (partially, since loading is only possible via the main menu).

Copy link
Contributor

Choose a reason for hiding this comment

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

  • When the window is resized the GUI gets stretched for a few seconds before coming back to norma

Hm, strange, i haven't found that)

  • It would be nice to have bigger graph as examples, a few hundred nodes at least. When I was doing this task 3 years ago we had a requirement to support full graphs with up to 10000 nodes (you don't have this requirement)

You are totally right!

  • When creating a vertex I need to input some data to be stored in it but there seems to be no way to view that data anywhere in the app

Yep, only ID's. It would be good to implement (f.e. user needs to see what data have nodes inside the community))

  • The algorithm for finding SCCs crashes the app with java.lang.ArrayIndexOutOfBoundsException: Only 15 colors supported on "test_graph"

Seems to be and UI integration issue, cant say anything about it. SCC was totally tested as a unit

  • For the layout algorithm, the buttons don't seem to work, nothing happens when I press them. 💡 And what do each of the sliders represent? Some meaningful names would really help.

I repied to this issue in the comments below. Sliders represent the parameters of the T-FDP model, there is an explanation of it in the code. #toaddfaqbutton ;)

@@ -0,0 +1,134 @@
package util
Copy link
Collaborator

Choose a reason for hiding this comment

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

💡 More edge-cases are needed. You basically have three variations of the same graph with most of the graph tests only using them. E.g. what if something breaks on a graph with a single vertex, with a single edge, with two parts not connected to each other...

import util.annotations.TestAllGraphTypes
import util.setupAbstractGraph

class CommunitiesFinderTest {
Copy link
Collaborator

Choose a reason for hiding this comment

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

💡 I know the algorithm is not implemented by you but still would be nice to have at least a single test with a more complex graph (with more than one vertex), just to ensure it works at all

Comment on lines +23 to +25
fun `graph is undirected, check its view and FAQ button`() {
// I'm not sure if we can consider this as an integration test
// Imho it's an integration test, due to UI's connection with VM + there is more than 2 components (view/vm, or front/back)
Copy link
Collaborator

Choose a reason for hiding this comment

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

❗️ I would say its just a bad test where several things are combined and its hard to say what exactly is tested.

First, you put a graph into a view model and then check that FAQBox displays the right graph name. I won't say this is an integration test since you actually put a string into the view model and just check that this string is displayed. The sole purpose of this string is to be displayed so I would argue this is a single component even though several system levels (view model and view) are involved.

Second, you put an undirected graph into the view model and check that it correctly determined the type of edges of the graph. I would also argue that this is a single component: you test the functionality of the view model, that it is able to read the graph.

Some examples of what I would consider as integration tests:

  1. Import a graph from some of your supported formats and then run an algorithm on that graph: this way you would check that the graph importing component of your system correctly interacts with the implemented algorithms.
  2. Closer to what you did, if you imported a graph instead of creating it manually in the test's code and then checked that FAQBox displays the correct graph name, I would also accept that as an integration test (the components interacting are import system and view model / UI).

Comment on lines +11 to +12
import org.junit.Rule
import org.junit.Test
Copy link
Collaborator

Choose a reason for hiding this comment

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

💡 There is a problem with your test setup. In all tests but this you use JUnit 5 (org.junit.jupiter:junit-jupiter-api:5.10.2) but for this UI test you use JUnit 4 (org.jetbrains.compose.ui:ui-test-junit4:1.6.2), probably because Android and, by extension, Compose doesn't support JUnit 5. Because of that, to make Gradle run all of the other tests I have to specify tasks.test { useJUnitPlatform() } in build.gradle.kts but than this test is not being run and vice versa. There probably is a way to make them work together but it is out of my concern.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yep, i found out that only at the end, bc i couldn;t find any examples of UI testing in case of compose using the JUnit4, so i managed to delete the task , that caused problems with unit-tests)

Copy link
Contributor

Choose a reason for hiding this comment

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

Btw, only recommendation i saw - to delete the task)

Comment on lines +54 to +56
val allEdgesDirected = edgeViewModels.all { it.value.isDirected() }

assert(allEdgesDirected) { "Not all edges are directed" }
Copy link
Collaborator

Choose a reason for hiding this comment

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

❗️

  1. Why do you expect edges of an undirected graph to be directed? I think this works only because you have used an empty graph and for an empty collection of edges all { ... } returns true.
  2. This assert is the one from Kotlin's stdlib, it will for only when JVM is launched with assertions enabled (-ea flag, it seems to indeed be enabled in tests) and then throw AssertionError on failure. What you need here is assertTrue() from JUnit.

@TimPushkin
Copy link
Collaborator

TimPushkin commented May 31, 2024

Now, I need to grade you. Each of you had to implement a "main" algorithm, two "classical" algorithms, implement saving/loading of graphs into one of the formats, write unit tests for all the functionality you have implemented and write at least a single integration test for the app.

  • Karim Shakirov:

    • Main algo: communities (works, but I have some doubts about results translation from JetBrains API to your format)
    • Classical algos: cycles (inefficient subgraph creation), Bellman-Ford (ok)
    • Saving/loading: JSON (not implemented)
    • Unit tests: for all your algos (not enough tests for communities, but ok since the implementation is not yours) + for general model functionality (a lot of duplication), no tests for JSON IO (because there is no JSON IO, yeah)
    • Integration test: -
  • Mike Gavrilenko:

    • Main algo: layout (works automatically when modifying the model but there is no way to control its parameters through UI)
    • Classical algos: SCCs (ok), Dijkstra (ok)
    • Saving/loading: SQLite (saving works, even though there are some bugs; loading only works from the main menu, also has bugs; the whole implementation belongs to the model layer but it is partially directly tied to UI; overall it was the only IO format implemented when I reviewed the code, so you'll have some bonus points for that)
    • Unit tests: SCCs (ok), Dijkstra (ok), no tests for layout algo and SQLite IO
    • Integration test: a poor one but at least you've tried 💪
  • Daniel Vlasenco:

    • Main algo: key vertices (strange results for directed graphs but it's probably a problem of the chosen centrality itself; somewhat inefficient, has a redundant step)
    • Classical algos: bridges (ok), MST (many data copies)
    • Saving/loading: Neo4J (implemented after the deadline, so I haven't reviewed it; probably will be considered unimplemented but we'll see)
    • Unit tests: for all your algos (ok), no tests for Neo4J IO
    • Integration test: -

I'll give you some time to correct me if I'm wrong somewhere in my comments (focus on the problems I've highlighted in the general review message and in this message since they are the main ones). Let's say, I'll wait until 21:00 today and then I'll tell the grades to your teachers.

@shakareem
Copy link
Contributor

Hello!! Actually, Mike worked with SqLite and I worked with JSON.

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.

I wanted to try out Neo4J but there are no instructions on how to set this thing up (I have no idea what AuraDB is). Of course I could ask Google but it is your responsibility to explain how to use your app. My point is that there should be instructions in README or even in UI.

@spisladqo The code looks like it should do something meaningful but I cannot verify it since there are no tests and no instructions. Maybe I'll add you some points for this but not much since the implementation came after the deadline and I cannot verify whether it actually works.

Comment on lines +7 to +9
object Neo4jRepositoryHandler {
var neo4jRepo: Neo4jRepository? = null
private set
Copy link
Collaborator

Choose a reason for hiding this comment

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

💡 A singleton with a complex state is usually not a good programming pattern since you introduce a global state available from everywhere in the program and it's not clear where it is used

Comment on lines +11 to +12
var isRepoInit = false
private set
Copy link
Collaborator

Choose a reason for hiding this comment

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

💡 You don't need this as a separate property with its own backing field, you can just check neo4jRepo != null

Suggested change
var isRepoInit = false
private set
val isRepoInit: Boolean
get() = neo4jRepo != null

Comment on lines +72 to +77
val driver = GraphDatabase.driver(uri, AuthTokens.basic(user, password))
driver.session().executeWrite { tx ->
tx.run {
"MATCH (v) RETURN v LIMIT 1"
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

💡 I thought, Neo4jRepository is responsible for database interaction. You could've created a companion object inside it and place this function there to make it available even when the repository is not instantiated.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks, I thought about this exact problem and didn't come up with something good, so ended up with something easy.

private fun checkIfCredentialsAreValid(uri: String, user: String, password: String): Boolean {
try {
val driver = GraphDatabase.driver(uri, AuthTokens.basic(user, password))
driver.session().executeWrite { tx ->
Copy link
Collaborator

Choose a reason for hiding this comment

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

❗️ I think sessions should be closed after use but this one is not. You should've used it as driver.session().use { ... } to make sure it is always closed.

Copy link
Collaborator

@TimPushkin TimPushkin May 31, 2024

Choose a reason for hiding this comment

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

❗️ Actually, the same also goes for the driver itself.

Comment on lines +178 to +181
override fun close() {
session.close()
driver.close()
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

❗️ Does this ever get called? It looks like once it has been used it stays opened forever which is not right. The right way would probably be to close everything after the graph has been saved/loaded. This way you won\t need Neo4jRepositoryHandler as a global singleton since the database connection would be opened and closed locally in the code that handles saving/loading. If you want to let the user to load/save multiple graphs without re-entering their credentials, you should either just cache the credentials or leave the connection open but find some other way to close it at some moment.

"distinct labels(v) AS label"
).list()
}
println(result)
Copy link
Collaborator

Choose a reason for hiding this comment

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

💡 If you wanted to do logging, there are special libraries for that. You even have some of them imported in Gradle (org.slf4j:slf4j-api:1.7.36, ch.qos.logback:logback-classic:1.4.12) but I don't think I've seen you using them anywhere.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry, I think I just forgot to remove this piece. Yes, we imported a logger into Gradle, but we just ended up with throwing exceptions/error messages.

@qrutyy
Copy link
Contributor

qrutyy commented May 31, 2024

  • Mike Gavrilenko:

    • Main algo: layout (works automatically when modifying the model but there is no way to control its parameters through UI)
    • Classical algos: SCCs (ok), Dijkstra (ok)
    • Saving/loading: SQLite (saving works, even though there are some bugs; loading only works from the main menu, also has bugs; the whole implementation belongs to the model layer but it is partially directly tied to UI; overall it was the only IO format implemented when I reviewed the code, so you'll have some bonus points for that)
    • Unit tests: SCCs (ok), Dijkstra (ok), no tests for layout algo and SQLite IO
    • Integration test: a poor one but at least you've tried 💪

Good evening, Tim!


I wanna say few words about the project and our team work in whole.

First of all, thank you for your review. I didn’t expect this much of comments, thats very cool! 


I apologise, I had no time to get to the end of your comments, bc 1 hour is not enough to check them all and send some replies. 
Our project could have been more successful, and i wanna share some development details(

1. Start
At the start of the project, we have a lot of time developing the model. In my opinion, that stopped us a lil)

2. UI

I started developing the UI, while my team was dealing with other tasks. So when they finalized it, they were struggling a lot, diving in the world of Compose. -> UI wasn’t refactored, and really checked by other. (Thats my fault)

3. Layout + SQL

Layout also caused some issues. I couldnt test it, bc i was dealing with the stupidest bug of my life, while implementing the SQL connection. -> I couldn’t test the layout -> Till the pretty much last day I thought that it worked fine. Well, i managed to implement it the other way, using FFT, but that cut my ability to connect it with the UI (so i could set different parameters)

4. Integration tests
Integration tests were also implemented before i managed to fix the bug) So…. i couldnt make a “real” integration test and try to understand the topic of using TestContainers (as i understood, there is really no need to use them in case of SQLite). So i tried to use only backend-frontend connection, relying on definition of the “integration tests” that referred only to the relationship between two different layers of the system (backend, frontend, db in our example)

5. Some thoughts

Btw, I tried and was successful in saving the generics from deleting from project, but i had really no time, to handle exceptions, errors (type handling)


This project was a great experience. Thanks to my team!

@qrutyy
Copy link
Contributor

qrutyy commented May 31, 2024

  • , no tests for layout algo and SQLite IO

Was it required? (the layout testing)

As i understood, SQLite IO should be tested only as a part of integration test)

@spisladqo
Copy link
Contributor

Sorry, my fault that I didn't drop explanation on what Neo4j AuraDB is. You can try these properties, which are for a test database I used:

URI = neo4j+s://c7593bad.databases.neo4j.io
USER = neo4j
PASSWORD = 1UmNjK0StlwYP47tKIdWxPsx6rlC3ucXIXaGOkHISAQ

(and I didn't manage to do graph import yet, so only save functionality is there)

And also thank you for your review! It is very informative and helpful, these small (and sometimes big) things that were left unnoticed really have a very big impact on the whole project.

@TimPushkin
Copy link
Collaborator

@qrutyy

, no tests for layout algo and SQLite IO
Was it required? (the layout testing)

As i understood, SQLite IO should be tested only as a part of integration test)

Yes, of course, it's just a functionality the same as any other. You need to check that your SQL statements work at all. If in your test, for example, you just call a function that executes an SQL statement and creates a piece of model from it, that's a unit test since only the functionality of the SQLite IO is tested. If then you also run an algorithm on a graph you've imported from SQLite, then it would be an integration test since the algorithm is a piece of functionality completely independent from SQLite IO (you can unit-test it independently).

First of all, thank you for your review. I didn’t expect this much of comments, thats very cool! 


I apologise, I had no time to get to the end of your comments, bc 1 hour is not enough to check them all and send some replies.

Yeah, I wanted to give you more time but the project is pretty big so I've spent more time reviewing it than I initially anticipated. You don't have to answer all of my comments, most of them are just recommendations. I even would recommend you to answer them only if you have some questions or don't agree with me.

And regarding the fact that you haven't got enough time, this is absolutely normal. Working in teams is hard, especially in the first year when you have almost no experience. Everybody have some problems with these tasks every year.

@TimPushkin
Copy link
Collaborator

@spisladqo

Sorry, my fault that I didn't drop explanation on what Neo4j AuraDB is. You can try these properties, which are for a test database I used:

Tried it, saving indeed seems to work, though there is not much to verify visually :)

Anyway, I'll now go figure out what grades to give you all.

spisladqo and others added 4 commits June 1, 2024 09:54
* feat: add function to save graph with name to neo4j

* feat: add function to clear graph from neo4j, use it in save function

* fix: resolve merge conflict

* fix: no more crash when entering empty id of vertex to connect with

* feat: remove independent id's and class generic from Neo4jRepository class

* feat: add message when graph was or was not saved to neo4j

* feat: add neo4j repo handler object to operate with repository

* fix: bug with making graph names empty just before save, load or edit

* feat: add neo4j load dialog window

* feat: add on-start import window

* feat: apply theme colors to create and import dialog windows

* feat: introduce constants for database names

* feat: change neo4j repo loadGraph() return value, refactor code

* feat: change on-start import message

* feat: make Neo4jLoginDialog() composable

* refactor: add newlines to ends of some files
* docs: add link to Wiki

* docs: add WIP status to JSON

* fix: switch to GH link

* docs: fix grammar

* docs: remove 'All in all' heading
* build: remove koin, clean up dependencies

* fix: make main private

* refactor: move constants to their files

* fix: make app run with our custom theme

* fix: switch to 'by remember', where possible

* fix: optimise graph creation dialog window

* refactor: move util viewmodel functions

* refactor: move dialog windows to a separate folder

* fix: switch DBType from list to enum

* fix: remove whole viewmodel pass in FAQ

* refactor: take out RadioColumn, simplify EdgeView

* fix: move available algs logic into 'GraphVM'

* fix: make a general 'RunAlgoButton' for 'Analyze' tab

* refactor: rename 'utils' package to 'components'

* fix: update 'SetupGraphVM', make it shorter

* fix: make SetupGraphVM an object, rename it

* fix: make TFDPLayout an object

* refactor: glow up the syntax

* refactor: move FFT to viewmodel package

* fix: move UI-connect methods from SQL module

* fix: reduce box size in 'add vertex' layout

* fix: remove old DB's, add a new one

* refactor: change imports
* fix: correct queries path

* fix: adjust dialog window size
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.

4 participants