Rj Ewing

Ranch Hand
+ Follow
since Mar 09, 2016
Cows and Likes
Cows
Total received
1
In last 30 days
0
Total given
0
Likes
Total received
4
Received in last 30 days
0
Total given
12
Given in last 30 days
0
Forums and Threads
Scavenger Hunt
expand Ranch Hand Scavenger Hunt
expand Greenhorn Scavenger Hunt

Recent posts by Rj Ewing

okay, so it turns out I need to break down my rules a bit more and think about precedence, with separate rules for AND & OR. Heres a peek at what I ended up with

4 years ago
I am trying to write a PEG parser using parboiled to construct an AST that I can generate sql from.

The part that is giving me trouble are and/or expressions. My rules are written as follows:


The string I'm trying to parse is val = 1 AND val2 = 1 OR val2 = 0 AND val3 = 0

The tree should start with an OR Expression with a left expression of val = 1 AND val2 = 1 and a right expression of val2 = 0 AND val3 = 0

I'm not sure of the best way to get the following structure. The recursive call LogicalExpression() -> Expression() -> LogicalExpression() is where the issue stems.

Any thoughts/help with how to eliminate the left recursion would be great.
4 years ago
Last night, after your comment about me describing the situation still not making it clear, I thought up something similar to what you have in



I think I need to continue further with the refactor part of tdd, especially with the tests. I did realize that the setup was fairly complicated in these tests, but wasn't quite sure what to do about it. Look at what you've wrote, it seems just extracting the setup into methods makes the tests clearer.

Thanks for taking the time to explain your thought process, it's very helpful

Junilu Lacar wrote:Ok, I still have a few minutes to get this reply in. Consider these three tests:

If you read though these test carefully and understand their intent, there's actually a theme and progression here. The code does not make that apparent though. Some of it can be fixed by renaming the methods so that a pattern and relationship between them can easily be discerned. Another thing you can do is to factor out some of the repetitive setup details and make the intent more clear.

As for clarifying the test names, you could rename them like this:

Gotta go now. I'll add to this later.



that makes sense. I think during the tdd process this made sense, but now there are other tests that make this redundant.

Junilu Lacar wrote:I don't get the difference between these two tests:

public void getBioSamplesSameBioProjectForBcids()
public void getBioSamplesDifferentBioProjectForBcids()

When I compare the bodies of these two tests, the only difference I can pick out is that the first is adding getBioSample2ExperimentPackage() while the second one is adding getBioSample3ExperimentPackage() to the repository. Yet, I don't see anything in the code that explicitly tells me how Sample 2 and Sample 3 are different and how Sample 2 is related to the "SameBioProject" part of its test name and how Sample 3 is related to the "DifferentBioProject" of its test name.

That test code is not helping me connect the dots; instead it makes me wonder what I'm missing.



During the creation of the bioSample objects, the bioProject is set. bioSample2 & bioSample3 have different projects. This test is because the external API only allows me to fetch bioSamples from 1 bioProject at a time.
Would you consider it a code smell if we have to use Fake objects when testing? Or more specifically a Fake object returning Fake objects?

After using tdd with parts of the system that will use the code in the 1st post. I've seem to come to a design that uses a Factory to return the appropriate API Endpoint Request.

Then in tests I can provide a FakeFactory.

This FakeFactory will provide Fake Api Endpoint Request, where I can pass in an expectedResponse and return it with the execute() method.
4 years ago

Junilu Lacar wrote:EDIT: on second thought, if you renamed the test to getBioSamples_returns_empty_list_when_given_empty_bcids_list, then that's probably going to attach enough meaning to the new ArrayList<>() parameter.



Sounds good. Do you have any more suggestions? It has been very helpful/insightful having someone more experienced look through my code!

Paul Clapham wrote:Side issue: could I recommend



to get an empty (and immutable) List<Bcid>?



Thanks for the suggestion!

I have to infer from the assignment on line 15 and the assertion on line 16 that the new ArrayList is supposed to set up the an empty repository of BioExample BioSample objects.



Not quite. Bcids are a core entity in our application. BioSample are a concept in another system that we need to link to our Bcids.

Bcid is a bit strange. Externally to our system it represents a globally unique identifier registered to a naming service. Internally, a Bcid is a domain object. The internal Bcid object's identifier is known externally as a bcid. This is a legacy thing that is a bit confusing. I think this needs to be refactored. Something like the renaming the current Bcid domain object which includes a property "bcid" which is the identifier.

BioSamples consist of many gb's of genetic sequencing data and the database doesn't provide the ability to upload using the api. Users can only upload on their website. The way the api works is that we need to set a "marker" in the upload data. Then we can later query the BioSample database for all BioSamples with our "marker" (we use the bcid). However this will return all BioSamples with the bcid "marker", and we are only interested in a specific list, thus the "bcid" array that is passed in.

So basically the class gets all the BioSamples from the external database, and returns the BioSamples corresponding to the bcids list.

I've renamed the test to getBioSamples_returns_empty_list_when_given_empty_bcids_list. However maybe renaming the repository method to repository.getBioSamplesForBcids would help as well?
Here's the tests.

So I just implemented my first class using tdd. Overall, I think the process went much better then w/o tdd. Any feedback on the following code would be greatly appreciated.



Some thoughts that came to my mind are..

I seem to be passing the bcids list and bioSamples list around alot. I've thought about adding those variables as class properties, however the idea of having those in a repository seems a bit strange. However this current repository will most likely only be read only. Another thing is that the bioSamples list is being filtered a couple times. I'm not sure if this is acceptable to change/re-set a property variable multiple times in a function.

Another thing that pops up is the filterBioSamplesWithExperiment method. I'm actually doing 2 things here. Setting the experiments on the bioSample and filtering the bioSamples to only include bioSamples with experiments.
Do you start at the high level function, and work your way down?

If I know I want to do X, and to do that I need to interact with an external api, my database, and do some business logic....

I would start with the api for X, and address the details as needed? One thing that confuses me a bit is what is the process when you need another class? Do you finish working on the current class, mocking out the new class, then when finished with the current, move to the new? Or should I start working on the new class immediately?
4 years ago
So I've read clean code and the 4 principles of simple design books. They are super helpful and I feel like I will be referring to them / rereading them for a while. I also have refactoring to patterns, working effectively with legacy code, test driven development, and fowler's refactoring book and on the way. I'm sure it'll take me a while to get through them and fully understand.

However I am beginning to see the benefits of tdd in regards to application design.

Now I've got a question regarding the factory pattern...

Currently I've got an abstract class AbstractRequest which provides a generic implementation for communicating with external APIs.


Then I've got another abstract class which represents an external service


Then I have implementations for each endpoint


My original thinking was that AServiceRequest would have static factory methods to return the appropriate class for the api call to be executed


Then I would have a class as follows:


However I'm think that isn't the best design, as I'm not sure how to stub the execute() return value in a test of myClass.

Would the factory pattern be a better design? Then I would pass the factory into the myClass constructor. This seems like it would allow me to easily stub the execute() response, making testing easier.

I'm thinking the factory would be a central location to get the appropriate AServiceRequest subclass for the desired endpoint call. such as:


But this seems like it maybe isn't the Factory method as I'm not returning a AbstractRequest or AServiceRequest but an implementation class.

Is there something I'm missing that will make this difficult to test? Is this something other then the factory method?
4 years ago

Junilu Lacar wrote:Does that make sense?



sure does. Thanks
4 years ago

Junilu Lacar wrote:I'd have to examine some code to say for sure but it might. In these cases, it's usually a good idea to factor that knowledge out to something that falls under what Peter Coad calls a Moment-Interval Archetype in his writings about Modeling in Color.



After reading that article, it brought up some questions. The moment-interval class would be something like a ProjectMembers class? This is because members can be added/removed over time? I assume there wouldn't be a MI-Detail class involved and the ProjectMembers class would keep track of the User objects?

Then would it be a good idea to have only the Project be aware of it members and the User is not aware of their Projects?
4 years ago