Skip to content

tournament: Put inputs/expectations inline, not in files #152

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

Merged
merged 2 commits into from
Jul 12, 2016
Merged

tournament: Put inputs/expectations inline, not in files #152

merged 2 commits into from
Jul 12, 2016

Conversation

petertseng
Copy link
Member

The previous iteration of reading/writing files is a valuable experience
in itself, but dilutes the focus of this exercise. We should consider an
exercise dedicated to that task if necessary, as discussed in #122.

Note that this preserves all behavior of existing test files. In
particular, the expectation that an invalid line is ignored is
preserved. If you wish for this behavior to be changed, you should
discuss that at exercism/problem-specifications#286 before
we make that change here.

The function tally now takes only a &str (it previously took two
Path, one for input and one for output) and now returns only a
String (it previously returned a Result<u32> where the Ok
counted the number of valid lines).

This commit is necessary but not sufficient for the closing of #122.
Points not covered by this commit but requested by #122 include:

format!("{:30} | {:2} | {:2} | {:2} | {:2} | {:2}",
team, games, r.wins, r.draws, r.losses, points)
}).collect();
header + &lines.join("\n")
Copy link
Member Author

Choose a reason for hiding this comment

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

Note that for an empty input, this prints the header and nothing after. No test tests this behavior, so I have nothing to say about whether this appropriate.

@petertseng
Copy link
Member Author

petertseng commented Jul 2, 2016

amusing fact: Since the files output1.txt, output2.txt, output3.txt were pre-provided before this commit, I believe this means an empty implementation that does nothing will pass the tests.

Edit: That comment is incorrect, because the number of lines read will still succeed, but it's close. What I mean is you don't need to write the output file.

Edit: Yup. See #153.

pub fn tally(input_filename: &Path, output_filename: &Path) -> Result<u32> {
let reader = BufReader::with_capacity(2048, File::open(input_filename).unwrap());
let mut count = 0;
pub fn tally(input: &str) -> String {
Copy link
Member Author

@petertseng petertseng Jul 3, 2016

Choose a reason for hiding this comment

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

I would like a reminder on the idiomatic-ness of str and String. I will see if I can find an answer myself.

Copy link
Member Author

Choose a reason for hiding this comment

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

http://hermanradtke.com/2015/05/03/string-vs-str-in-rust-functions.html argues for using &str as argument. I will keep that.

On the other hand String makes the most sense for what I output since I'm concatenating in write_tally

@IanWhitney
Copy link
Contributor

This is good. I want to go through it a bit more carefully, but I don't think there's anything controversial here. As I mentioned in #122, no other languages use input/output files for this exercise. I don't think they are necessary.

@petertseng
Copy link
Member Author

squashed in the string suggestion since I'm pretty sure it's the way to go

@petertseng
Copy link
Member Author

a small rebase since both this and #155 removed some use lines (I just had to tell git "yup, all of them should remain removed")

@IanWhitney
Copy link
Contributor

With the removal of the File IO stuff, this problem could probably now be moved to a different spot in the order. It still requires a fair amount of work, but it's mostly just string parsing and some comparisons. Maybe it should move to somewhere in these problems?

  • hexadecimal
  • grade-school
  • queen-attack

@petertseng
Copy link
Member Author

Yeah now the list of skills is "string parsing, custom sorting, string formatting". I'm going to say after grade-school; both are problems that may see use of a HashMap to solve (store students by grade, store reults by team). Of course, if we have a desire to not put them together since they have too similar things, just say the word (that's why I mention it!)

The previous iteration of reading/writing files is a valuable experience
in itself, but dilutes the focus of this exercise. We should consider an
exercise dedicated to that task if necessary, as discussed in #122.

Note that this preserves all behavior of existing test files. In
particular, the expectation that an invalid line is ignored is
preserved. If you wish for this behavior to be changed, you should
discuss that at exercism/problem-specifications#286 before
we make that change here.

The function `tally` now takes only a `&str` (it previously took two
`Path`, one for input and one for output) and now returns only a
`String` (it previously returned a `Result<u32>` where the `Ok`
counted the number of valid lines).

This commit is necessary but not sufficient for the closing of #122.
Points not covered by this commit but requested by #122 include:
* Explain the input format. Covered by
  exercism/problem-specifications#254
* Explain behavior on invalid lines. Covered by
  exercism/problem-specifications#286
With the removal of the file I/O portion of this exercise (via the
previous commit and through discussion in #122) now this exercise
becomes easier and can be moved. The list of skills are now roughly:
string parsing, string formatting, custom sorting.

Also HashMap usage seems natural, as you want to store the results of
each team.

Moving it to after grade-school, another problem that may see HashMap in
its solution.
@petertseng
Copy link
Member Author

Oh, I originally moved between grade-school and queen-attack.

In the meantime, robot-simulator was also added to the exact same position.

I'll add it before robot simulator.

@petertseng
Copy link
Member Author

Merging soon since it seems that all that wants to be said has been said.

@petertseng
Copy link
Member Author

petertseng commented Mar 12, 2017

Amazing. According to exercism/problem-specifications#22 , tournament was intentionally designed to include file I/O. The Rust track was the first track to have this exercise.

Looks like that purpose has been lost since then, both in this track and others. C# is the only track with vestiges of that file I/O since it uses streams.

I generally think the file I/O portion is not well-suited for the testing style of Exercism, but I see that above we considered whether there can be an exercise specifically dedicated for file I/O (the grep exercise ostensibly requires file I/O too).

I am sorry to the creator of this exercise for playing my part in the exercise's diversion from its original purpose. It was in the name of giving the exercise some purpose at all.

petertseng added a commit that referenced this pull request Jul 7, 2021
This was made an error in Clippy recently, so we'll need to fix it if we
want CI to work.

According to https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow

What it does:

Checks for address of operations (`&`) that are going to be dereferenced
immediately by the compiler.

Why is this bad:

Suggests that the receiver of the expression borrows the expression.

Commentary as it applies to the Rust track:

I can get behind the idea that it's better not to mislead the reader of
the code about how many levels of reference the called function needs.

Most of these stem from a misunderstanding of what expressions were
already borrowed. They are listed below. Note carefully inconsistencies
introduced in sublist and tournament, and consider whether we have a
solution for this inconsistency before approving. The concern would be
any confusion it may cause to those learning Rust. It is consistent from
the standpoint of the type we're ultimately passing, but it's
inconsistent from the standpoint of what the call sites look like.

* Dominoes: The input is `&[Domino]`, and check takes `&[Domino]`.
  calling `check(&input)` passes `&&[Domino]` whereas we should call
  `check(input)` to pass `&[Domino]`
* DOT DSL: `iter` iterates over `&T`. Therefore the `name` is a `&&str`
  (recall that string literals in Rust produce `&str`) and we are
  iterating over a `[&str]` producing `&&str`; since `Node::new` takes
  `&str`, just `name` would be better than `&name`, which would pass
  `&&&str`
* grep: The patterns are string literals such as `"Agamemnon"`. Recall
  that string literals in Rust produce `&str`, and grep takes `&str`, so
  no additional `&` should be added. In fact, we should do this for the
  macro too, even though Clippy does not seem to catch those.
* pangram: Recall that string literals in Rust produce `&str`, and
  is_pangram takes `&str`, so no additional `&` should be added.
* sublist: The `v` was declared as `&[u32]`, and `sublist` takes two
  `&[T]`, so no additional `&` should be added. Inconsistency
  introduced: `sublist` is called with `&` in all other instances in
  this file because they are either slice literals or Vec, which do
  require the `&`.
* tournament: Recall that string literals in Rust produce `&str`, and
  `tally` takes `&str`, so no additional `&` should be added.
  Inconsistency introduced: The first four cases use a string literal
  and thus do not require `&`. The next cases use `String` (recall that
  we decided that this was the best way to show the multi-line strings
  in #152 (comment)),
  and therefore require `&`. Consider carefully whether this may be
  confusing to students that some require `&` and some not.
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.

2 participants