-
-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow reading multiple file solutions and exemploids #298
Conversation
@@ -0,0 +1,5 @@ | |||
defmodule SquareRoot.Cheating do | |||
def calculate(n) do | |||
Float.pow(n / 1, 0.5) |> floor() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This worked straight away, which I was quite happy about.
fn path, {:ok, code} -> | ||
case File.read(path) do | ||
{:ok, file} when is_nil(code) -> {:cont, {:ok, file}} | ||
{:ok, file} -> {:cont, {:ok, code <> "\n" <> file}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line brings the coverage down a bit, I can't test it because we don't have a multiple file exemploid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left a few nitpicks about code style, but the functionality works as expected 🎉. Great addition!
lib/elixir_analyzer.ex
Outdated
end | ||
|
||
exemploid_path = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The singular variable names confuse me now... may I suggest renaming?
solution_path
->solution_files
editor_path
->editor_files
exemploid_path
- >exemploid_files
code_path
->all_compiled_files
orall_analyzable_files
orall_files_for_analysis
? "code" is very vague 🤔 (I know, you didn't choose this name initially)
Maybe the keys in the Source
struct should be renamed too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I got lazy there :D
I left code_string
and code_ast
in Source
as they are, still vague but not really confusing in context.
lib/elixir_analyzer.ex
Outdated
params.path | ||
|> Path.join("lib") | ||
|> ls_r() | ||
|> Enum.filter(&String.ends_with?(&1, ".ex")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I initially read ls_r
as "list files right" and didn't get it for a while... maybe the function could be named ls_recursive
?
On the other hand, I wonder if this function can be replaced by:
Path.join([params.path, "lib", "**", "*.ex"]) |> Path.wildcard()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, that's nice!
{:ok, nil}, | ||
fn path, {:ok, code} -> | ||
case File.read(path) do | ||
{:ok, file} when is_nil(code) -> {:cont, {:ok, file}} | ||
{:ok, file} -> {:cont, {:ok, code <> "\n" <> file}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume that the case is_nil(code)
is only there because of the first iteration and initial value of the accumulator. What if we did something like this, appending new lines instead of prepending? We would end up with one extra newline at the very end, but it shouldn't matter, right? (suggested code not tested)
{:ok, nil}, | |
fn path, {:ok, code} -> | |
case File.read(path) do | |
{:ok, file} when is_nil(code) -> {:cont, {:ok, file}} | |
{:ok, file} -> {:cont, {:ok, code <> "\n" <> file}} | |
{:ok, ""}, | |
fn path, {:ok, code} -> | |
case File.read(path) do | |
{:ok, file} -> {:cont, {:ok, code <> file <> "\n"}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It almost doesn't matter, but in some unlikely cases it makes a line in an error message off-by-one (see CI fail before reverted commit). Line number kind of loses meaning when you have multiple files, but after reflection, I'd still like to keep the nil
.
Co-authored-by: Angelika Tyborska <angelikatyborska@fastmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the review, I'm excited about this feature!
It's interesting how every little tiny change breaks a test in a ~99% coverage codebase. It's annoying for changes in error messages, but it makes refactoring much safer.
lib/elixir_analyzer.ex
Outdated
params.path | ||
|> Path.join("lib") | ||
|> ls_r() | ||
|> Enum.filter(&String.ends_with?(&1, ".ex")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, that's nice!
lib/elixir_analyzer.ex
Outdated
end | ||
|
||
exemploid_path = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I got lazy there :D
I left code_string
and code_ast
in Source
as they are, still vague but not really confusing in context.
This reverts commit b0b04ce.
Closes #276.
The analyzer can now accept multiple file exemploids (as long as they are listed in the config file) and multiple file solutions (even if they are not mentioned in the config file).
This gives more freedom to exercise builders, but also allows students to structure their solution as they please (especially CLI users) while still benefiting from the analyzer advice.
The compiler warning module has been changed to handle multiple file compilation.