Closed vexorian closed 11 years ago
This is an amazing idea! I'm always looking for new features of Greed and this is certainly one. Maybe we can go one step further and think about not only the source code, the test code, the unit test code, the input output template, but also other things? And we can also adjust old configuration to be consistent under this configuration template and it's just cool!
I guess what we need is to decide how it will work.
I wonder if the config system allows something like this:
greed { templates { pathPattern = "sol" cpp { tmplFile = "Template.cpp" testTmplFile = "TestTemplate.cpp" spec.longIntTypeName = "long" files = "in, out, exttester" #declare the names of the files in { # we use the names declared in files="" as a section tmplFile = "Input.in" filename = "${ClassName}.in" override = True } out { # we use the names declared in files="" as a section tmplFile = "Onput.out" filename = "${ClassName}.in" override = True } exttester { tmplFile = "Ext.cpp" filename = "${ClassName}Tester.cpp" override = False # For example, this would allow User to put most of the tester in another file instead # of the ${ClassName}.cpp one. } } } }
The usual code template and tester template would stay outside of the files thing, because unlike custom files, you need two templates to make them work. I wonder if there is a work around though.
First about the configuration file, are you asking that if the files
variable can be used to declare a list of templates?
If so, it can. You can do files = [in, out, exttester]
, I'm not quite sure about its details, I guess it doesn't matter.
The offical doc for the configuration lib is here https://github.com/typesafehub/config.
And about the second question of yours, you're saying that the source code template actually contains the test template, so it must be special treated, right? You're right about that. I think a possible workaround is that, we can bind a template name or a property name to bind to, to each template, and the generated code is bound to the model with the name. For example,
greed {
templates {
pathPattern = "sol"
cpp {
spec.longIntTypeName = "long"
# there should be a better name, templates has already been used
# and I'm not quite sure about how to define an array here, let's just leave it like this
templates = [
test {
# Here we have several options, we can have the template with "bindTo" property
# not generated and just write the data in the model
# or we just don't generate file if there's no `fileName` property defined in this template
bindTo = "TestCode"
templateFile = "TestTemplate.cpp"
}
source {
# In this template we can use "${TestCode}" since it's bound by the last template
templateFile = "Template.cpp"
fileName = "${ClassName}.cpp"
override = true
}
unitTest {
foo = bar
}
in {
# ...
}
]
}
}
}
This way we can abstract away the particularity of default template and use them as they're normal templates. This approach may encounter the order issues. The user must define the templates in order that the current template can only use the previous bound ones, which may not be a good user experience. Of course this is just a simple idea. What do you think?
@vexorian Here is a conf file which may satisfy our idea. https://github.com/shivawu/topcoder-greed/blob/tmpl-seq/src/test/resources/test.conf However, it has a drawback that, we cannot split files, the output file can only be one file. This may limit the original idea where you may want to split samples into different files. What do you think?
Do you mean that we cannot make a different output file for each test case? That sounds difficult to do, but I think that the easiest approach rather than complicating the configuration file, would be for the user to write a script to split the output file if he really needs the files split.
Questions:
Like if I did :
templates { makefile { override = True outputFileName = "${Problem.Name}/Makefile" } lang.cpp.templateSeq = [ test, source, testcases, problem, makefile ] lang.cpp.templates = ${greed.templates} { makefile.templatefile = "Makefile.template" } }
?
Shouldn't
source { override = false outputFileName = "${Problem.Name}" }
Have outputFileName = "${Problem.Name}.${outputFileExtension}" ?
Yes, that's what I meant. It would be nice to split the sample to different files so that the tester can easily go through them by the file structure, otherwise we may need to define a syntax for the samples (maybe XML), and it may be complicated and not user-friendly due to its complexity.
I agree that it's a good idea that user can do some self work. Here we cannot do this in the configuration file elegantly because the configuration file is not as powerful as the template engine, and it would be messy to write all these logic in the configuration. What I thought was that, define the sample template to be a template like samples.template
, then define some writing-to-file logic in the template, like
${foreach}
${write to file}
...
${end}
${end}
Unfortunately, the template engine is not powerful enough to handle this, either (maybe, I have not thought this through), So my next step of the plan is to write a new template engine, of course this one is even bigger, we have to do these things one-by-one.
Another idea is to define some post processing hook for the templates, for example:
templates {
samples {
tmplFile = ...
postProcessing = greed.InputFileSplitter
}
}
This can be a workaround of this with enough generality, in which user can apply predefined behaviour for all the templates. And we still have the flexibility of defining other post-processing hooks for other templates, which means it's not only for the sample template. What do you think of this one?
About the questions, funny thing is that all your questions are related to each other. :-)
greed.lang.cpp.templates
.${greed.templates}
, maybe you're not familiar with the configuration library,greed.lang.cpp.templates
just inherits all the properties from greed.templates
with its own other properties,
defined in the following {}
.${outputFileExtension}
to reference to the property in the current scope. However there're 2 problems here. First one is the outputFileExtension
may not have been defined yet, second the config library only permits absolute path referencing, and these limitations throws us at this awkward situation, any better idea?In my opinion the default should stay saving tests inside the code, as executing a single source file is straightforward and requires little tinkering. But it would be nice to allow people to choose otherwise.
My initial idea was just to let greed create ACM-style input that has the number of test cases as the first integer. Then the tester can read multiple cases. But I see the use in allowing the test cases to be separated in files.
I honestly think the template engine is too complex as is. Allowing some pre/post processing might be better. Actually, it would be nice to be able to have triggers. For example, I would like to call a command whenever a file is created. I think the cleanest way to do something like this is by giving Greed err... plugin support. But that's bigger work for later.
@vexorian Sorry for late response. I was outside travelling.
https://github.com/shivawu/topcoder-greed/blob/tmpl-seq/src/test/resources/test.conf
I update the template with an afterGen
hook, by which we can let user to execute custom external commands,
and they can write scripts to do whatever they want.
What do you think of this way?
It seems good.
I've done most coding work, including:
Check it out, in the tmpl-seq branch. I hope we can finish this and release a 2.0 in a few days or weeks.
Features still missing:
Excellent, I am currently busy writing editorial, will make sure to check it out tomorrow.
I have been testing it.
I tried to make an input file template (That has all tests in the same file and begins with the number of tests. After the changes I added to the new pull request it generates this for SRM594 FoxAndGo3:
6 3 "o.o" ".o." "o.o" 3 "..." ".o." "..." 5 "xxxxx" "xxoxx" "xo.ox" "xxoxx" "xxxxx" 5 ".xox." ".o.ox" "x.o.o" "ox.ox" ".ox.." 5 "o.o.o" ".ox.." "oxxxo" "..x.." "o.o.o" 3 "..." "..." "..."
We probably need a way to render string valuess without quotes. Perhaps a custom renderer?
I see what you mean about the string without quotes. Could you please share your templates with me so that we can discuss what's the best way to do this.
The config file will get complicated, for sure, because we have moved the source,test,unittest logic from code to config. But it should not affect the users, they don't need to write the whole config.
About the share.basicTemplate, I don't see that's quite useful, since we will be trading two lines of common code with a deeper level of inheritance semantic and we still need to write the ${greed.shared.basicTemplate}
on each templateDef
. Seems also a big boilerplate.
In fact, the default value can be set in the code so that we don't need to do these initialization, I just thought this way it's more clear what the default value is.
About the last point, do you mean that, when OutputFileExtension
is "", the file will not get created? In my opinion, it will create a file named OutputFileName.
(note the last dot). But I haven't tested it. Anyway, this is a bug.
Well then, it is a bug. When OutputFileExtension is not declared, the file is not created and there is no mistake report.
Also, not all files are supposed to have extension. There has to be a way to be able to create a file without a '.' in it. For example, what if user wants to create a "Makefile" file?
Sorry about that, I didn't notice pasting the template would break the comment because of < characters. Here it is again: The template:
${NumOfExamples} ${<foreach Examples e} ${<foreach e.Input in} ${<if in.Param.Type.Array} ${in.ValueListLength} ${<foreach in.ValueList v } ${v} ${<end} ${<else} ${in.Value} ${<end} ${<end} ${<end}
My plan is to have the output in a different file and the checker would open the two files. Then it would be possible to add test cases like you'd add cases to files when competing in non-topcoder contests. If there was a way to remove quotes when rendering ${v} ...
I updated the string util renderer with a unquote
command, try it out.
But be aware of the empty string, which must be special treated while reading.
Empty string is indeed a problem. Although they are rare in problems. I was going to rely on reading the whole line instead of just the next string, because white space inside strings would also be complicated to handle. Maybe {"aa...aa", "xxx..."} format is preferable to some in input files, but that would need the custom tester to parse input.
Yes, that's usually how it's done. You can start writing a parser, which may be quite complicated and let's see how can we handle all the cases with clean and simple code. BTW, I fix the empty file extension bug.
After build.gradle is updated, you should use gradle fatJar
to do the package thing.
fatJar generates a jar that contains the com folder. But the plugin still doesn't instance. I will take a further look.
So is it working now?
The fatjar creates a jar that seems to contain everything, but for some reason the arena hangs when I try to open the plugin. It doesn't happen when I compile using the old build script.
Yesterday, during the match I found an unfortunate bug in tmpl-seq, greed was sending empty source files to TopCoder.
That's very strange. You can open the java console when you started arena, and see what's going on there. And what bug? Sorry for your loss. - -
Sorry for taking this long, I've been busy.
I tested with console, and it turns out that Greed halts when it can't read the version file. Which is not added to the jar, even when building with ./gradlew fatjar
I've implemented the afterGen hook, and also the problem statement template, how did it go with the testcase template?
Not terribly bad: https://dl.dropboxusercontent.com/u/95690732/greed/template.in https://dl.dropboxusercontent.com/u/95690732/greed/template.out
I just got too busy and couldn't finish the tester yet. Well, I do have this that translates input to output: https://dl.dropboxusercontent.com/u/95690732/greed/C%2B%2B-gcc.in.test.tmpl
But I guess a checker is needed.
On Wed, Nov 6, 2013 at 10:01 AM, Shiva Wu notifications@github.com wrote:
I've implemented the afterGen hook, and also the problem statement template, how did it go with the testcase template?
— Reply to this email directly or view it on GitHubhttps://github.com/shivawu/topcoder-greed/issues/38#issuecomment-27875112 .
Good job. No problem, I'll pick up where you left.
I pushed a testcase template and a c++ parser.
I've merged the input and output into one file, and each testcase use a --
as its prefix to identify a testcase is following.
Please help me test it and let me know your opinion, including the format of the testcase, the implementation of the template, and so on.
This is not going to be the default behavior, right?
I think that as a sample it is good to have the input and output in the same file. -- is not bad.
I have been testing on many problems and so far no issues.
What I was considering is the usability. If we split into two files, the user will have to edit two files when trying to add new cases, especially in a fierce contest, it will cost more time, and our parser is more complicated to parse two files. Also, if we have the number of testcases in the front of the file, the user has to change that too, so I removed it.
What I tried is that by default Greed will use the templates that put test cases inside the source code (like before) ? Or will it use these external files?
Yes, I'm hoping the default behaviour is to separate the code with the data.
It will be more complex to setup, it needs the sample file in the work directory when the program is executed.
Yes, of course we need to come up with a convention about the file location and stuff. What's your suggestion?
As far as putting the test cases in a separate file, I don't think it can be much better than the current idea. Just make sure to leave the old templates in the jar and it will be just ok.
Yes, the old template will be left there for backward compatibility. Maybe there's someone out there like the old way.
Me, for example.
Actually, I have all test cases in the source file, but only the test cases and in a very convenient bracket-based format. http://vexorian.blogspot.com/2013/10/c-and-python-topcoder-generic-testers.html
Wow! I'm really impressed. Your templates are very cool. I haven't read your blog before (blogspot is not accessible in my area...) If you're willing to, we can add your template to the codebase and release them with 2.0, with adjustment to the new features, if needed.
Also, I'm almost finished with the new features, what do you think of the templates now? If you have no further concerns, we can start with the other templates, copying the C++ one. You can be in charge of the Python one, since I'm not much of a Pythoner.
On Mon, Nov 11, 2013 at 10:23 AM, vexorian notifications@github.com wrote:
Me, for example.
Actually, I have all test cases in the source file, but only the test cases and in a very convenient bracket-based format. http://vexorian.blogspot.com/2013/10/c-and-python-topcoder-generic-testers.html
— Reply to this email directly or view it on GitHubhttps://github.com/shivawu/topcoder-greed/issues/38#issuecomment-28168233 .
Chenyang WU Shanghai Jiao Tong University Cell: +86-15801929580 Address: No. 800 Dong Chuan Rd, Minhang District, Shanghai
My templates are a bit specific and need an external tester library file. So I never thought of adding them to Greed's jar, but if you want them it is cool. Actually, now with the custom templates, the tester library file can be a template too that is called only the first time you open a problem.
I must admit I am not very good with python I/O, but I can try.
A good thing about a sample file is that if user adds some sample cases, the sample cases can stay even if (s)he switches language.
Yes, that's the default behaviour now, since the override property of these templates are false. However, if the user click 'Regenerate code', it will be overwritten since it has a force regenerate behaviour. But old files will be backed up.
On Mon, Nov 11, 2013 at 11:03 AM, vexorian notifications@github.com wrote:
A good thing about a sample file is that if user adds some sample cases, the sample cases can stay even if (s)he switches language.
— Reply to this email directly or view it on GitHubhttps://github.com/shivawu/topcoder-greed/issues/38#issuecomment-28170197 .
Chenyang WU Shanghai Jiao Tong University Cell: +86-15801929580 Address: No. 800 Dong Chuan Rd, Minhang District, Shanghai
I've finished all the external test template, including python. It's easier than I thought. Test it out and let me know your opinions.
2.0-beta is released, guys! @vexorian @wookayin @starforever @ashashwat @tomtung @jbransen Test it out when you get time, tons of new features, you'll be impressed.
Great job, @shivawu and @vexorian. I was keeping my eyes on your impressive workings, and it's time to check it out for further enhancements. Cheers!
2.0-beta is not working for my case, so far.
This was the error I got.
Greetings from Greed Problem : MarblesInABag Score : 1000 Set problem error, message says "null"
After I reloaded my config, it says -
Reloading your configuration from "/Volumes/CoreHD/Repository/TC//greed.conf"
There is no greed.conf anymore in my root dir. After asking to regenerate the source code, it gives me the same error -
Greetings from Greed Problem : MarblesInABag Score : 1000 Set problem error, message says "null"
After I copied default.conf from source as greed.conf in my root directory, I got these errors.
Greetings from Greed Problem : MarblesInABag Score : 1000 Generating template [filetest] Template file "builtin filetest/cpp.tmpl" not found Generating template [source] Template file "builtin source/cpp.tmpl" not found Generating template [testcase] Template file "builtin testcase/testcases.tmpl" not found Generating template [problem-desc] Template file "builtin problem/desc.html.tmpl" not found All set, good luck!
On Tue, Nov 12, 2013 at 8:19 PM, Jongwook Choi notifications@github.comwrote:
Great job, @shivawu https://github.com/shivawu and @vexorianhttps://github.com/vexorian. I was keeping my eyes on your impressive workings, and then I will check it out for further enhancements. Cheers!
— Reply to this email directly or view it on GitHubhttps://github.com/shivawu/topcoder-greed/issues/38#issuecomment-28298741 .
I'm not sure what's the error is. It works at my side. I updated the README with the way to see detailed logging. Please following the instructions and raise an issue with the detailed exceptions with it. Thanks.
I have yet to sort out the problem completely but so far I can certainly say this, it is now packed with one hell of feature-set.
Thanks a lot for the awesome work.
You're welcome! Nice usage about the post processing hooks, I've never thought it that way. If you have any other feature requests or ideas, do not hesitate to share it!
Hello, I have an idea that requires more work than a simple commit.
The template engine is very powerful, we can even create unit tests.
I think it would be useful to allow Greed to create other kinds of files, not just unit tests or source, but anything according to configuration.
In configuration:
So now a file called ProblemName.in will be generated in the folder. When generating it the template engine will use file "InputTemplate.in" .
So in this specific case, the template file would be the necessary template to generate an ACM-style input file for the problem. This should be possible with the template engine. Although maybe we need an array length replacement variable. Then the user would call a custom tester template that reads test cases from a file.
There should be support for more than one custom file. For example, input and output.
There are many uses for this. For example generating project files. Or run scripts, and whatever the user could think about.