Passing Arguments within If Statement - function

I'm trying to pass arguments between two files, and am encountering issues. I'm trying to parse a message for the word 'foo' in it, and create a function that will check if the message is only 'foo' or perhaps is a word like 'foot', which contains foo but isn't the word foo. Here's the two files
test2.py
import os, sys
from functiontest import function
message = 'foo'
check = 0
if 'foo' in message:
function(message,check)
print(check)
print('bar')
else:
check = 0
if check == 0:
print('foo not recognized')
and the function file
functiontest.py
import os, sys
def function(a,b):
print('checking message')
a = a.split()
print(a)
if a[0] == 'foo':
b = 1
print(b)
return b
else:
b = 0
return b
When run, it indicates that when b is set to 1 and passes it, it doesn't get passed correctly and remains 0. I want it to pass the argument check to be 1 if it is detected that the word isn't exactly 'foo' so that the message will appear saying that 'foo is not detected'. What am I doing wrong?
Follow up question: Once check is confirmed as 0 within the if statement, is there a way to break the statement and not execute the next lines that are within that if statement and rather skip to the else statement? I would prefer to include this somehow in the function to make the main code look cleaner, because I could include more embedded if statements but I want to avoid that if possible.

You're throwing away the return value of function, then printing check, which was never changed from the original value of 0. I believe your intent was to reassign check with the return value of the function:
check = function(message,check)
print(check)

Related

Lua: Can I select a table in script via argument in command line?

I have a lua script with many tables like
local a = {1,2,3}
local b = {1,2,3}
local c = {1,2,3}
etc. and one function like
test = {}
function test.set(args)
for x, y in pairs(args) do
....
end
end
test[arg[1]](arg[2])
Now I want to choose one of the tables via command line to use it in the function. I tried
lua MyScript.lua set a
and I get the error
lua: MyScript.lua:1249: bad argument #1 to 'pairs' (table expected, got string)
stack traceback:
[C]: in function 'pairs'
MyScript.lua:1249: in field '?'
MyScript.lua:1266: in main chunk
[C]: in ?
It kind of makes sense because I pass a string. But I don't know how to select the table I want to use in the function. Can anybody help me?
local all_your_tables = {a = {1,2,3}, b = {1,2,3}, c = {1,2,3}}
...
test[arg[1]](all_your_tables[arg[2]])

EOF Error During Dict Slice

I am trying to compile monthly data in to an existing JSON file that I loaded via import json. Initially, my json data just had one property which is 'name':
json_data['features'][1]['properties']
>>{'name':'John'}
But the end result with the monthly data I want is like this:
json_data['features'][1]['properties']
>>{'name':'John',
'2016-01': {'x1':0, 'x2':0, 'x3':1, 'x4':0},
'2016-02': {'x1':1, 'x2':0, 'x3':1, 'x4':0}, ... }
My monthly data are on separate tsv files. They have this format:
John 0 0 1 0
Jane 1 1 1 0
so I loaded them via import csv and parsed through a list of urls and set about placing them in a collective dictionary like so:
file_strings = ['2016-01.tsv', '2016-02.tsv', ... ]
collective_dict = {}
for i in strings:
with open(i) as f:
tsv_object = csv.reader(f, delimiter='\t')
collective_dict[i[:-4]] = rows[0]:rows[1:5] for rows in tsv_object
I checked how things turned out by slicing collective_dict like so:
collective_dict['2016-01']['John'][0]
>>'0'
Which is correct; it just needs to be cast into an integer.
For my next feat, I attempted to assign all of the monthly data to the respective json members as part of their external properties:
for i in file_strings:
for j in range(len(json_data['features'])):
json_data['features'][j]['properties'][i[:-4]] = {}
json_data['features'][j]['properties'][i[:-4]]['x1'] = int(collective_dict[i[:-4]][json_data['features'][j]['properties']['name']][0])
json_data['features'][j]['properties'][i[:-4]]['x2'] = int(collective_dict[i[:-4]][json_data['features'][j]['properties']['name']][1])
json_data['features'][j]['properties'][i[:-4]]['x3'] = int(collective_dict[i[:-4]][json_data['features'][j]['properties']['name']][2])
json_data['features'][j]['properties'][i[:-4]]['x4'] = int(collective_dict[i[:-4]][json_data['features'][j]['properties']['name']][3])
Here I got an arrow pointing at the last few characters:
Syntax Error: unexpected EOF while parsing
It is a pretty complicated slice, I suppose user error is not to be ruled out. However, I did double and triple check things. I also looked up this error. It seems to come up with input() related calls. I'm left a bit confused, I don't see how I made a mistake (although I'm already mentally prepared to accept that).
My only guess was that something somewhere was not a string. When I checked collective_dict and json_data, everything that was supposed to be a string was a string ('John', 'Jane' et all). So, I guess it's something else.
I made the problem as simple as I could while keeping the original structure of the data and for loops and so forth. I'm using Python 3.6.
Question
Why am I getting the EOF error? How can I build my external properties data without encountering such an error?
Here I have rewritten your last code block to:
for i in file_strings:
file_name = i[:-4]
for j in range(len(json_data['features'])):
name = json_data['features'][j]['properties']['name']
file_dict = json_data['features'][j]['properties'][file_name] = {}
for x in range(4):
x_string = 'x{}'.format(x+1)
file_dict[x_string] = int(collective_dict[file_name][name][x])
from:
for i in file_strings:
for j in range(len(json_data['features'])):
json_data['features'][j]['properties'][i[:-4]] = {}
json_data['features'][j]['properties'][i[:-4]]['x1'] = int(collective_dict[i[:-4]][json_data['features'][j]['properties']['name']][0])
json_data['features'][j]['properties'][i[:-4]]['x2'] = int(collective_dict[i[:-4]][json_data['features'][j]['properties']['name']][1])
json_data['features'][j]['properties'][i[:-4]]['x3'] = int(collective_dict[i[:-4]][json_data['features'][j]['properties']['name']][2])
json_data['features'][j]['properties'][i[:-4]]['x4'] = int(collective_dict[i[:-4]][json_data['features'][j]['properties']['name']][3])
That is just to make it a bit more readable, but that shouldn't change anything.
A thing I noticed in your other part of code is the following:
collective_dict[i[:-4]] = rows[0]:rows[1:5] for rows in tsv_object
The thing I refer to is the = rows[0]:rows[1:5] for rows in tsv_object part. In my IDE, that does not work, and I'm not sure if that is a typo in your question or of that is actually in your code, but I imagine you want it to actually be
collective_dict[i[:-4]] = {rows[0]:rows[1:5] for rows in tsv_object}
or something like that. I'm not sure if that could confuse the parser think that there is an error at the end of the file.
The ValueError: Invalid literal for int()
If your tsv-data is
John 0 0 1 0
Jane 1 1 1 0
Then it should be no problem to do int() of the string value. E.g.: int('42') will become an int with value 42. However, if you have an error in one, or several, lines of your files, then use something like this block of code to figure out which file and line it is:
file_strings = ['2016-01.tsv', '2016-02.tsv', ... ]
collective_dict = {}
for file_name in file_strings:
print('Reading {}'.format(file_name))
with open(file_name) as f:
tsv_object = csv.reader(f, delimiter='\t')
for line_no, (name, *x_values) in enumerate(tsv_object):
if len(x_values) != 4:
print('On line {}, there is only {} values!'.format(line_no, len(x_values)))
try:
intx = [int(x) for x in x_values]
except ValueError as e:
# Catch "Invalid literal for int()"
print('Line {}: {}'.format(line_no, e))

How to implement a basic Lua function in Conky?

I am trying to add a function to my Conky which prints the length of a string for debug purposes. The code, inside a file called test.lua, is pretty trivial:
function test(word)
return string.len(word)
end
...and I load it like this. In my conky.config section I have:
lua_load = '/home/xvlaze/test.lua',
lua_draw_hook_pre = 'test'
...in the conky.text section I have:
${lua test "fooo"}
...where test is the name of the function and fooo the string to test.
The expected result should be a printed 4 in Conky, but instead of that I get:
conky: llua_do_call: function conky_test execution failed: /home/xvlaze/test.lua:2: attempt to index a nil value (local 'string')
conky: llua_getstring: function conky_test didn't return a string, result discarded
I have browsed through the documentation, but I can't find anything. Does anybody know where the failure is?
Several guidances on how to implement functions in Conky:
First of all: YOU MUST USE conky_ BEFORE YOUR FUNCTION'S NAME.
Otherwise, you will get the following error when running your Conky:
attempt to call a nil value
Secondly: YOU MUST ALWAYS RETURN A VALUE.
I don't mind repeating it - it is crucial. Otherwise, you will get:
function foobar didn't return a string, result discarded
function_result
...in your terminal, and your Conky will be left empty of values related to your extra code. Nothing will be printed regarding your function.
Last but not least: YOU MUST ALWAYS CALL YOUR FUNCTION LIKE:
lua_load = '/path/to/function.lua',
-- Whatever content...
${lua function_name function_parameter1 function_parameterN} -- In case you use more than one parameter.
In summary, a dummy function template could be:
MAIN FILE (conky.conf):
conky.config = {
-- Whatever content... Lua styled comments.
lua_load = '/path/to/function.lua',
}
conky.text = [[
# Whatever content... In this section comments are started with '#'!
${lua function_name parameter}
]]
FUNCTION FILE:
function conky_function_name(parameter)
-- Whatever content... Remember this is Lua, not conky.text syntax. Always use '--' comments!
return whatever -- No return, no party. A function MUST always return something!
end

How to call a function with less arguments that is set (Python 3)

I am making a terminal emulator in Python 3. The commands are being stored in functions, like:
def rd(os_vartmp, os_vartmp2):
if os_vartmp == None:
print('rd [path] [-S]')
print('Delete a folder')
else:
if os.path.isfile(os_vartmp) == True:
if os_vartmp2 == '-S': print('a')
else:
print(ERR5)
a = input('Command: ')
The terminal works like this:
Asks user for input
Splits the input
Uses the first part of input to search a function in locals
If there is one, uses the rest part of input as argument
Calls the function
The thing here is, when i call the function 'rd' with, for example, 'rd "boot.py" -S' it works just fine. But if i need to call it like this: rd "boot.py", it throws me a error about 1 argument given when 2 are required. Is there a fix for that?
You can make an argument optional by assigning a value in the method definition. For example:
def Add(x=0, y=0):
return x+y
If you input only one value, y will default to 0. If I wanted to give y a value but have x fall back on it's default value I could do Add(y=10). I hope this helped!
Have you tried this?
def rd(os_vartmp, os_vartmp2="-S"):
Instead of trying to get null value, which would require rd("boot.py",null), you can ser default value and then you can do rd("boot.py").
Hope it works.

check each character from a string by pgsql function

I want to make a function which will check each character of a string.
For example, lets take a word "pppppoooossssttt", in this case the function will return a warning if same character repeated for more that 2 times. Here 'p' is repeated for 5 times. So the function will return a warning message.
If you're able to install plpython on your setup, this is what I would do. Then you could simply place this test inside a "WHERE" clause of a standard SQL function. It's immutable so it will only be called once, and it always returns True so it won't affect the results of a SQL query. Postgres has had some pretty shaky python implementations but either they or EnterpriseDB cleaned things up in the latest release.
CREATE OR REPLACE FUNCTION two_or_less(v text)
RETURNS BOOLEAN AS $$
#If the string is two characters
#or less, we can quit now.
ct = len(v)
if ct < 3:
return True
import plpy
warned = set()
a,b,c = v[:3]
for d in v[2:]:
if a == b == c:
if a not in warned:
warned.add(a)
plpy.warning('The character %r is repeated more than twice in a row.' % a)
a,b,c = b,c,d
return True
$$ LANGUAGE 'plpython3u' IMMUTABLE;