I am a beginner in Python and i am reading Wrox's "Beginning Python Using Python 2.6 and Python 3.1"... There is one certain example in chapter 8 about using files and directories that has troubled me a lot... The following function is supposed to create (if it doesn't exist) and write in a text file:
def write_to_file():
f=open("C:/Python33/test.txt","w")
f.write("TEST TEST TEST TEST")
f.close()
When i run the function nothing happens, no text file is created and no error message is returned...
When i run the code in IDLE, command by command, it works perfectly...
What is wrong with the function???
Python's picky about indentation, from what I remember of it:
def write_to_file():
f = open("C:/Python33/test.txt", "w")
f.write("TEST TEST TEST TEST")
f.close()
# On top of that, you need to actually run the function.
write_to_file()
I think this is because of indentation, do it like this:
def write_to_file():
f=open("C:/Python33/test.txt","w")
f.write("TEST TEST TEST TEST")
f.close()
Related
I am looking at any library (in java) that can help me generate a dummy JSON file to test my code for e.g The JSON file can contain random user profile data-name, address, zipcode
I searched StackOverflow and found this link, found the following link : How to generate JSON string in Java?
I think the suggested library https://github.com/DiUS/java-faker, seems to be useful, however because of security constraints I cannot use this particular library. Are there any more recommendations?
Use for instance Faker, like that:
#!/usr/bin/env python3
from json import dumps
from faker import Faker
fake = Faker()
def user():
return dict(
name=fake.name(),
address=fake.address(),
bio=fake.text()
)
print('[')
try:
while True:
print(dumps(user()))
print(',')
except KeyboardInterrupt:
# XXX: json array can not end with a comma
print(dumps(user()))
print(']')
You can use it like that:
python3 fake_user.py > users.json
Use Ctrl+C to stop it when the file is big enough
I am attempting to programmatically run a series of Rspec tests and capture the output of each.
What I have so far is this:
RSpec.configure do |config|
config.formatter = :json
end
out = StringIO.new
err = StringIO.new
RSpec::Core::Runner.run([file], err, out)
This does run the given file correctly, and in the terminal that I run this script from I see the JSON output that I expect... but since I'm giving the runner a StringIO stream, I would expect it to write the JSON output to that instead of stdout. In this case, the out stream is always empty.
Anyone have any idea what I'm doing wrong?
To run a series of Rspec tests I use Rake and to record their output I use a RSpec::Core::RakeTask in which I can specify rspec_opts with which you can pass a location and format for rspecs output.
Example:
Rakefile
require 'rake'
require 'rspec/core/rake_task'
desc "Run tests, recording their output"
RSpec::Core::RakeTask.new(:spec) do |task|
task.pattern = 'spec/*_spec.rb'
task.rspec_opts = '--format documentation' +
' --format json --out logs/output.json'
end
I made a basic github project demonstrating this at https://github.com/SamuelGarratt/rake_demo
The above Rakefile assumes your rspec tests are in a folder called 'spec' and end in '_spec'. Type 'rake spec' on the command line to run all the rspec tests and have their output recorded.
What I'm trying to do:
I'm trying to change the formatting on a csv file from space delimited to comma delimited.
What I've done:
I can ingest the csv file just fine, and print the output row-by-row to the console. That code looks like this:
with open(txtpath, mode='r', newline='') as f:
fReader = csv.reader(f)
for rows in fReader:
print(rows)
This does exactly what it's supposed to, and spot checking the output confirms that the rows are being read correctly.
The Problem:
According to the official Python3 Documentation on csv.writer, "If csvfile is a file object, it should be opened with newline='' 1." My code looks like this:
with open(csvpath, 'w') as g:
gWriter = csv.writer(g, newline='')
gWriter.writerows(rows)
so all together, it looks like this:
with open(txtpath, mode='r', newline='') as f:
fReader = csv.reader(f)
for rows in fReader:
print(rows)
with open(csvpath, 'w') as g:
gWriter = csv.writer(g, newline='')
gWriter.writerows(rows)
However, when I run the code with both Pycharm (Anacondas 3.4 selected as project interpreter) and from the console with python3 mycode.py, both results tell me that newline "is an invalid keyword argument for this function" and references line 42, which is where my writer object is instantiated. I ran it through the debugger and it craps out as soon as I try to create the writer object. If I don't add the newline argument it asks for a dialect specification, so that doesn't work, either.
I'm sure there's something blindingly obvious that I'm missing, but I can't see it.
To avoid this error , open the file in 'wb' mode instead of 'w' mode. This will eliminate the need for newline.
Corrected code is as follows:
with open(csvpath, 'wb') as g:
gWriter = csv.writer(g)
gWriter.writerows(rows)
The wording is just a bit vague. The file should be opened with newline='', but newline is not a valid option for csv.writer() itself.
newline does not work in with open('output.csv', 'a',newline='') as fp. It will return back an error:
'newline' is an invalid keyword argument for this function
I used 'ab' method and it worked without blank lines between the lines:
with open('output.csv', 'ab',) as fp
I met the same problem and the solution may sound funny but it does work.
I actually changed the position of the newline argument to be in front of mode as below:
with open("database.csv", newline="", mode="a") as database2:
You can test and see the result.
The following will do
with open('filename_inCSV.csv',mode='r') as csvfile:
or
with open('filename_inCSV.csv','r') as csvfile:
To be honest go has spoiled me. With go I got used to having a strict formatting standard that is being enforced by my editor (vim) and is almost accepted and followed by everybody else on the team and around the world.
I wanted to format JSON files on save the same way.
Question: How to auto format/indent/lint json files on save in vim.
In one command, try this:
execute '%!python -m json.tool' | w
You could then add you own key binding to make it a simpler keystroke. Of course, for this to work, you need to have Python installed on your machine.
If you are keen on using external tool and you are doing some work with json, I would suggest using the jq:
https://stedolan.github.io/jq/
Then, you can execute :%!jq . inside vim which will replace the current buffer with the output of jq.
%!python -m json.tool
or
%!python -c "import json, sys, collections; print json.dumps(json.load(sys.stdin, object_pairs_hook=collections.OrderedDict), ensure_ascii=False, indent=4)"
you can add this to your vimrc:
com! FormatJSON %!python -m json.tool
than you can use :FormatJson format json files
Thanks mMontu and Jose B, this is what I ended up doing:
WARNING this will overwrite your buffer. So if you OPEN a json file that already has a syntax error, you will lose your whole file (or can lose it).
Add this line to your ~/.vimrc
" Ali: to indent json files on save
autocmd FileType json autocmd BufWritePre <buffer> %!python -m json.tool
you need to have python on your machine, of course.
EDIT: this next one should not overwrite your buffer if your json has error. Which makes it the correct answer, but since I don't have a good grasp of Vim script or shell for that matter, I present it as an experimental thing that you can try if you are feeling lucky. It may depend on your shell too. You are warned.
" Ali: to indent json files on save
autocmd FileType json autocmd BufWritePre <buffer> %!python -m json.tool 2>/dev/null || echo <buffer>
A search for JSON plugins on vim.org returned this:
jdaddy.vim : JSON manipulation and pretty printing
It has the following on description:
gqaj "pretty prints" (wraps/indents/sorts keys/otherwise cleans up)
the JSON construct under the cursor.
If it does the formatting you are expecting then you could create an autocmd BufWritePre to format when saving.
Here is my solution. It doesn't exactly address the question part of "on save" but if you perform this action before save it will output errors you can then fix before save.
Also, it depends on only one external tool -- jq -- which has become the gold standard of unix shell JSON processing tools. And which you probably already have installed (macOS and Linux/Unix only; idk how this would behave in Windows)
Basically, it's just:
ggVG!jq '.'
That will highlight the entire JSON document then run it through jq which will just parse it for correctness, reformat it (e.g. fix any indents, etc), and spit the output back into the Vim editor.
If you want to parse only part of the document, you can highlight that part manually by pressing v or V and then run
!jq '.'
The benefit here is that you can fix subsections of your document this way.
Vim Autoformat
https://github.com/Chiel92/vim-autoformat
There is this Vim plugin which supports multiple auto format and indent schemes as well as extending with custom formatters per filetype.
https://github.com/Chiel92/vim-autoformat#default-formatprograms
Note:
You will need to have nodejs and js-beautify installed as vim-autoformat uses these as the default external tool.
npm install -g js-beautify
Another solution is to use coc-format-json.
I did some organizing (though some of it had nothing to do with vim) and to write the script by yourself on the neovim!
solution1: neovim
1-1: write the script by yourself
Neovim allows Python3 plugins to be defined by placing python files or packages in rplugin/python3/ in a runtimepath folder)
in my case
- init.vim
- rplugin/python3/[your_py_file_set].py
- rplugin/python3/fmt_file.py
The fmt_file.py as following
# rplugin/python3/fmt_file.py
import pynvim
import json
#pynvim.plugin
class Plugin:
__slots__ = ('vim',)
def __init__(self, vim):
self.vim = vim
#pynvim.command('FormatJson', nargs='*', range='')
def format_json(self, args, rg):
"""
USAGE::
:FormatJson
"""
try:
buf = self.vim.current.buffer
json_content: str = '\n'.join(buf[:])
dict_content: dict = json.loads(json_content)
new_content: str = json.dumps(dict_content, indent=4, sort_keys=True)
buf[:] = new_content.split('\n')
except Exception as e:
self.vim.current.line = str(e)
afterwards run: :UpdateRemotePlugins from within Nvim once, to generate the necessary Vimscript to make your Plugin available. (and you best restart the neovim)
and then, you open the JSON file that one you want to format and typing: :FormatJson in the command. all done.
don't forget to tell vim where is your python
" init.vim
let g:python3_host_prog = '...\python.exe''
and pip install pynvim
1-2: use tool.py
where tool.py is located on the Lib/json/tool.py
:%!python -m json.tool
solution2: command line
If you already install the python, and you can open the command line:
python -m json.tool "test.json" >> "output.json"
solution3: python
I write a simple script for those things.
"""
USAGE::
python fmt_file.py fmt-json "C:\test\test.json"
python fmt_file.py fmt-json "C:\test\test.json" --out_path="abc.json"
python fmt_file.py fmt-json "test.json" --out_path="abc.json"
"""
import click # pip install click
from click.types import File
import json
from pathlib import Path
#click.group('json')
def gj():
...
#gj.command('fmt-json')
#click.argument('file_obj', type=click.File('r', encoding='utf-8'))
#click.option('--out_path', default=None, type=Path, help='output path')
def format_json(file_obj: File, out_path: Path):
new_content = ''
with file_obj as f:
buf_list = [_ for _ in f]
if buf_list:
json_content: str = '\n'.join(buf_list)
dict_content: dict = json.loads(json_content)
new_content: str = json.dumps(dict_content, indent=4, sort_keys=True)
if new_content:
with open(out_path if out_path else Path('./temp.temp_temp.json'),
'w', encoding='utf-8') as f:
f.write(new_content)
def main():
for register_group in (gj,):
register_group()
if __name__ == '__main__':
main()
you can search for 'vim-json-line-format' plugin, Open a file in Normal mode, move your cursor on the json line, use <leader>pj to show formated json by print it, use <leader>wj could change the text to formatted json.
Invalid json can not format!
Use ALE to auto-format on save
Configure ALE to format JSON
add the following to .vim/vimfiles/after/ftplugin/json.vim:
let b:ale_fix_on_save = 1 " Fix files when they are saved.
I have a C code which takes a file as input, processes it and gives a number as output. I want to build a html webpage which takes the file path as input, gives it to the C code. C code processes it and output(integer) is displayed in browser. Can you please suggest me how to go about this? Are there are any prebuilt softwares to do this?
If C code is used to produce a command line utility then you could call it while generating a web page:
#!/usr/bin/env python
import subprocess
from bottle import request, route, run, template # http://bottlepy.org/
command = ['wc', '-c'] # <-- XXX put your command here
#route('/')
def index():
filename = request.query.filename or 'default' # query: /?filename=<filename>
output = subprocess.check_output(command + [filename]) # run the command
return template("""<dl>
<dt>Input</dt>
<dd>{{filename}}</dd>
<dt>Output</dt>
<dd>{{output}}</dd></dl>""", filename=filename, output=output)
run(host='localhost', port=8080)
Run this script or paste it into a Python console, then open your browser and pass a filename (a path on the server) as a query parameter:
$ python -mwebbrowser http://localhost:8080/?filename=/etc/passwd
wc -c prints number of bytes for each input file. It is executed on the server.
If C code is available as a library; you could use ctypes module to call a C function from Python e.g., to call printf() C function from libc library:
#!/usr/bin/env python
import ctypes
from ctypes.util import find_library
try:
libc = ctypes.cdll.msvcrt # Windows
except OSError:
libc = ctypes.cdll.LoadLibrary(find_library('c'))
n = libc.printf("abc ")
libc.printf("%d", n)