I am new to competitive programming and I would try to do a custom build in my Sublime Text 3. I would like a build where I can input a file and redirect the output of the file to a file.
problem.py content:
print('test')
variable = input()
print(variable)
input.in content:
word
When I use the following command line it works perfectly :
python problem.py <input.in >output.txt
however now I would try to do a build on SBT3
{
"cmd": ["C:/ProgramData/Anaconda3/python.exe", "-u", "$file", " <input.in", " >output.txt"],
"file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)"
}
I am sure to select the right build, only test appears on the output, and nothing gets in the output file. Do I miss something ?
Thanks!
This is an incredibly common issue; there's a lot of advice floating around on the internet that says that if you're creating a sublime-build
system you should be using cmd
in it to specify what gets executed. This works, but in many cases it's more work and doesn't do what you expect it to to.
In a nutshell, when you use cmd
, you're telling Sublime "See the first item in the list? Find that and run it, and then provide every other item in the list as arguments to that command".
If you're just doing something like ["python", "-u", "$file"]
that does exactly what you want; run Python, tell it to execute a file without doing output buffering.
When you try to do something like ["python", "$file", "< input.txt", "> output.txt"]
you're literally providing an argument of "< input.txt"
to Python, which it does not understand.
The construct of redirecting input and output is something that your shell knows how to do (windows command prompt, bash
on Linux/MacOS, etc). In order to use input redirection you need to get the shell to execute the program so that it can do the redirection for you.
Fortunately this is as easy as using shell_cmd
in place of cmd
; that passes the string you provide directly to whatever shell the system is using for execution.
In your case, that would look like this:
{
"shell_cmd": "C:/ProgramData/Anaconda3/python.exe \"$file\" < input.in > output.txt",
"file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)",
"selector": "source.python",
"working_dir": "$file_path",
"env": {"PYTHONIOENCODING": "utf-8"}
}
The shell_cmd
is a replica of exactly what you would type in the shell where you to execute the command manually; here we've removed the -u
because that makes Python not buffer it's output; since you're sending the output to a file, you most definitely want buffering.
We also add a selector
so that Sublime knows that this build is for Python code (not needed, but it's nice to have the Tools > Build System
set to Automatic
and then builds "Just Work").
Most importantly, working_dir
sets what folder is considered the "current" directory while the build is running. Without this, the input file and output file will be assumed to be at some random location on your hard drive which is most likely not what you expect.
By setting the working directory to be the same directory that the file that you're building is in, you can be sure that if you have test.py
, input.in
and output.txt
in the same folder, it's going to work the way you want.