JSON is not a human friendly config format; it has harsh rules for quoting, brackets and commas and most importantly has no intuitive facility for comments. YAML should be preferred to JSON for config. However, ConfigParser is even better and a list of IPs need only be space separated (eg hosts = config.get('hosts').split() , quite simple ) or you could even make the <i>value</i> of the parameter be a JSON list if you really like to type brackets and quotes. The "simplest" approach is in fact to use the most <i>idiomatic</i> approach that everyone recognizes, and if you're doing config files in python that means ConfigParser.<p>Edit: it seems they went with a newly invented language called json-config that looks like a hybrid of JSON and C-style comments. That's fine, but using an invented config format that nobody knows isnt the "simplest" approach at all. It's the most <i>complicated</i> solution. When people use invented idioms in their projects for things like config and logging that have widely accepted idiomatic solutions included in Python std
lib that's an immediate red flag.
<i>For example, here I needed a configuration file that will have a list of IP addresses, which I will iterate in for loop.<p>This was the smallest requirement that I needed for my problem.</i><p>My instinctive solution would be even simpler --- a text file with one IP per line, similar to a HOSTS file.
Related, in today's Farnam Street email, he linked to an article examining the psychology behind why humans prefer complex things to the simple[0].<p>It's especially interesting because most other psychological biases appear to be the result of a mental short-cut. Perhaps we see something complex and mistakenly infer the preconditions were complex, and that somehow makes it more valuable.<p>An especially interesting quotation, relevant to this forum is in that article, by a sportswriter: "Most geniuses—especially those who lead others—prosper not by deconstructing intricate complexities but by exploiting unrecognized simplicities."<p>[0] <a href="https://www.farnamstreetblog.com/2018/01/complexity-bias/" rel="nofollow">https://www.farnamstreetblog.com/2018/01/complexity-bias/</a>
> At that time, I was accessing only one device (only one IP address).<p>> But could see that in future (in few months to one year), I will need to do the same set of command on more devices.<p>IMHO, this statement represents one of the biggest design smells in programming. It's usually a bad idea to write software you may need in the future. Circumstances change. Writing code is expensive and coding in anticipation of what you might need is often a waste of time.<p><i>Write code you need now, not code you may need later.</i><p>It makes sense to think ahead but if you're spending a lot of time writing code you might need, then you're probably doing something wrong.
The first complexity in the ConfigParser example comes from trying to parse something like a python list.<p>Just accept ips seperated by spaces, users will be thankful.<p>The other complexity is using the raw loading and converting from bytes.<p>ConfigParser can give you back strings and read the file for you.<p>Here is a full example:<p><pre><code> import ConfigParser
import io
import shlex
def main():
config = ConfigParser.ConfigParser(allow_no_value=True)
config.read('config_ini.ini')
testing_1 = shlex.split(config.get('other', 'list_queue1'))
print(testing_1)
if __name__ == '__main__':
main()
</code></pre>
This is the same as a comment I made on the website, but for the benefit of any python devs here.
This is a pretty confused article. The author starts with a list of useful things which he then deems 'too complicated', and ends up with using a JSON based config file. Ok. But the things he listed are not too complex, and the solution is a simple line-based config file of IP addresses:<p><pre><code> import netaddr, sys
ips_to_connect_to = [*netaddr.IPGlob(ip) for ip in open(sys.argv[1])]
</code></pre>
Those two lines handle points 1, 2 and 3 of his 'nice to haves'. You could easily add 4 and 5 in under 10 lines. You could expand it to read from stdin rather than a fixed file easily enough as well.
Command line args would have been the simplest solution imho.
Works simple for simple cases and power users will create a bash wrapper anyway.<p>Hard to be wise without knowing the context, but I avoid config files as much as possible, because:<p>- Where does the config file live on different machines?<p>- What if I want to have 2 configurations on one machine?<p>- What if I need to change the list dynamically?<p>`for ip in sys.args` would give you most flexibility.
It's sad that the perfect template for all non-binary data, configuration and otherwise, has been around for quite some time: S-expressions.<p>Nobody but lispers use them. Why?
Is that really simpler than writing the list out in a file called config.py like<p><pre><code> ips=['192.x....',
'192.y',
'192.z']
</code></pre>
Then in your main<p><pre><code> from config import ips
</code></pre>
Or does distributing as an .exe preclude this?<p>Edit: formatting
YAML - I am not a big fan these days. Perhaps I am have OCD on format, but with YAML ordering is “up to the user”. At least INI has a somewhat “header/section” so it looks more organized. The “yes Yes True TRUE true 1 => True (python)” is flexible but can be seen as negative if again you are like me OCD. You can enforce style guideline in your dev team, but for end-user, probably worth reconsidering your strategy.<p>The reasons I’d consider JSON for configuration are (1) when the configuration is really simple and short, and (2) I don’t want an extra dependency. You don’t want to handcraft for a larger data structure, and context switch between your terminal and JSON validator.<p>I like INI-style configuration file. But ConfigParser’s API is horrible, and everyone seems to like tweak and invent their own “INI” format.<p>Instead, for those really need a good configuration file, I recommend TOML [1].<p>For data file, either YAML or JSON are fine. But each comes with gotcha. Trailing comma in JSON is invalid (which is probably #1 “wtf what’s wrong with my json”). For YAML you need to be very careful with “do I want an int or do I want a string.”<p>[1]: <a href="https://github.com/toml-lang/toml" rel="nofollow">https://github.com/toml-lang/toml</a>
Actually this is pretty simple if you use ConfigParser properly:<p><pre><code> # test.ini
[host1]
ip = 1.2.3.4
[host2]
ip = 5.6.7.8
[host3]
ip = 9.10.11.12
# config.py
import configparser
c = configparser.ConfigParser()
c.read("test.ini")
ips = [ c[host]['ip'] for host in c.sections() ]</code></pre>
I'm really a fan of JSON config files for simple configuration. In a strongly typed language you can parse it into a "Settings" object with one line of code and work with the object.<p>Creating the settings object at least for C# is just a matter of pasting it into a website (after removing all of the sensitive bits of course)
Not directly related to the article, but can someone explain why people from Eastern Europe and Russia tend to drop most of the articles (like "a", "an", "the") when speaking/writing English?