I am playing around with python3 in idle and after discovering what Pig Latin is I am trying to write a couple functions and am confused about where to start/what python specific words/functions I should be using.
(i) 1 parameter -I am trying to translate words from pig latin back to English. It would always end with "ay" and only have one hyphen. Essentially I am trying to remove the hypen and "ay" at the end of the pig latin word. I believe I need to start by finding the position of the hyphen. Then I want it to extract from the string 2 substrings: the portion before the hyphen and the portion between the hyphen and the "ay" at the end. For example, when given the string "at-thay", the two substrings are "at" and "th". Following this I want to combine the two substrings to create the English word. (example above would return "that")
(ii) I want a function that takes a single parameter, a string, and finds the first position within that string where any of the characters "aeiouAEIOU" appears. For example, given the string "is", your function should return 0, and given the string "Pig", I want the function to return 1. If the string doesn't have any of the listed vowels in it at all, such as with the string "shh", then the function should return the length of the string, which would be 3 in this example.
(iii) I want a function that returns the translation of a single word from English to Pig Latin. The translation consists of everything from the first vowel onward then a hyphen, the portion of the word that preceded the first vowel, and the letters "ay".
I know this is a tall order but any help with any of these 3 would greatly help!
you could do:
def unPigWord( word ):
"""This function takes any Pig Latin word and returns that word in English."""
parts = word.split( "-" )
return parts[1][0: len(parts[1])-2] + parts[0]
def findVowel( word ):
for i, char in enumerate( word ):
if char in "aeiouAEIOU":
return i
return i + 1
def pigWord( word ):
fvi = findVowel( word )
return word[fvi:] + "-" + word[0:fvi] + "ay"
Related
In my sql code, I receive a input string as a regular match's filter, I want to have the whole string as a normal string, even it includes some special characters.
Just look below:
do $$ declare
jdata jsonb='[{"name":"Dog 3*240+1*120"}]'::jsonb;
vfilter1 text='dog';
vfilter2 text='3*240+1*120';
vexists bool=false;
begin
select jdata #? concat('$[*] ? (#.name like_regex "',vfilter1,'" flag "i")')::jsonpath into vexists;
raise notice 'exists:%',vexists; --the result is true
select jdata #? concat('$[*] ? (#.name like_regex "',vfilter2,'" flag "i")')::jsonpath into vexists;
raise notice 'exists:%',vexists;-- the result is false
end;
$$ language plpgsql;
the string 3*240+1*120 include + and * characters, perhaps this causes the regular match have them as special character. In my code, I just want to have the whole vfilter string includes all special characters together as a normal string for the regular match.
What should I do?
You should read the documentation for the feature you are using.
The optional flag string may include one or more of the characters i
for case-insensitive match, m to allow ^ and $ to match at newlines, s
to allow . to match a newline, and q to quote the whole pattern
(reducing the behavior to a simple substring match).
Have a file keywords.tx with
Commands:
keywords = 'this' & 'way'
;
StartWords:
keywords = 'bag'
;
Then a file mygram.tx with
import keywords
MyModel:
keyword*=StartWords[' ']
name+=Word[' ']
;
Word:
text=STRING
;
'''
My data file has one line with "bag hello soda this way".
Would like to see result have attributes of keyword='bag' name='hello soda' and command='this way'.
Not sure how to get grammar to handle: keywords words keywords making sure that 2nd keywords are not included in the words. Another way to express is startwords words commands
If I understood your goal you can do something like this:
from textx import metamodel_from_str
mm = metamodel_from_str('''
File:
lines+=Line;
Line:
start=StartWord
words+=Word
command=Command;
StartWord:
'bag' | 'something';
Command:
'this way' | 'that way';
Word:
!Command ID;
''')
input = '''
bag hello soda this way
bag hello soda that way
something hello this foo this way
'''
model = mm.model_from_str(input)
assert len(model.lines) == 3
l = model.lines[1]
assert l.start == 'bag'
assert l.words == ['hello', 'soda']
assert l.command == 'that way'
There are several things to note:
You don't have to specify [' '] as a separator rule in your repetitions as by default whitespaces are skipped,
To specify alternatives use |,
You can use a syntactic predicate ! to check if something is ahead and proceed only if it isn't. In the rule Word this is used to assure that commands are not consumed by the Word repetition in the Line rule.
You can add more start words and commands simply by adding more alternatives to these rules,
If you want to be more permissive and capture commands even if user specified multiple whitespaces between command words (e.g. this way) you can either use regex matches or e.g. specify match like:
Command:
'this ' 'way' | 'that ' 'way';
which will match a single space as a part of this and than arbitrary number of whitespaces before way which will be thrown away.
There is a comprehensive documentation with examples on the textX site so I suggest to take a look and go through some of the provided examples.
I just want to format a decimal number for output to a simple CSV formatted file.
I feel like I'm stupid, but I can't find a way to do it without leading zeroes or spaces, of course I can simply trim the leading spaces, but there has to be a proper way to just format like I that, isn't there?
Example
define variable test as decimal.
define variable testString as character.
test = 12.3456.
testString = string(test, '>>>>>9.99').
message '"' + testString + '"' view-as alert-box. /* " 12.35" */
I tried using >>>>>9.99 and zzzzz9.99 for the number format, but both format the string with leading spaces. I actually have no idea what the difference is between using > and z.
The SUBSTITUTE() function will do what you describe wanting:
define variable c as character no-undo.
c = substitute( "&1", 1.23 ).
display "[" + c + "]".
(Toss in a TRUNCATE( 1.2345, 2 ) if you really only want 2 decimal places.)
Actually, this also works:
string( truncate( 1.2345, 2 )).
If you are creating a CSV file you might want to think about using EXPORT. EXPORT format removes leading spaces and omits decorations like ",". The SUBSTITUTE() function basically uses EXPORT format to make its substitutions. The STRING() function uses EXPORT format when no other format is specified.
The EXPORT statement will format your data for you. Here is an example:
DEFINE VARIABLE test AS DECIMAL NO-UNDO.
DEFINE VARIABLE testRound AS DECIMAL NO-UNDO.
DEFINE VARIABLE testString AS CHARACTER NO-UNDO.
test = 12.3456.
testRound = ROUND(test, 2).
testString = STRING(test).
OUTPUT TO VALUE("test.csv").
EXPORT DELIMITER "," test testRound testString.
OUTPUT CLOSE.
Here is the output:
12.3456,12.35,"12.3456"
The EXPORT statement's default delimiter is a space so you have to specify a comma for your CSV file. Since the test and testRound variables are decimals, they are not in quotes in the output. testString is character so it is in quotes.
I want to transpose row into column and then save words in CSV file. The problem is only last value of column after transpose is save in file, and if i append string with list, it save in file but characters not words.
Anyone help me to sort it. Thanks in advance
import re
import csv
app =[]
with open('afterstem.csv') as f:
words = [x.split() for x in f]
for x in zip(*words):
for y in x:
res=y
newstr = re.sub('"', r'', res)
app = app + list(res)
#print("AFTER" ,newstr)
with open(r"removequotes.csv", "w") as output:
writer = csv.writer(output, lineterminator='\n', delimiter='\t')
for val in app:
writer.writerow(val)
output.close()
The output save in file look like this:
But i want "Bank" in one cell.
Simply use
for column in zip(*words):
newrows = [[word.replace('"', '')] for word in column]
app.extend(newrows)
to put all columns one after another into the first column.
newrow = [[word.replace('"', '')] for word in column] creates a new list for each column with double quotes stripped and wrapped into a list and app.extend(newrow) appends all of these lists to your result variable app.
You got your result because of your inner loop and in particular its last line:
for y in x:
...
app = app + list(res)
The for-loop takes each word in each column and list(res) converts the string with the word into a list of characters. So "Bank" becomes ['B', 'a', 'n', 'k'], etc. Then app = app + list(res) creates a new list that contains every item from app and the characters from the word and assigns that to app.
In the end you got a array containing every letter from the file instead of a array with all words in the file in the right order. The call to writer.writerow(val) then wrote each letter as it's own row.
BTW: If your input also uses tabs to delimit columns, it might be easier to use list(csv.reader(f, lineterminator='\n', delimiter='\t')) instead of your simple read with split() and stripping of quotes.
I would like to split a string like this in Access 2000 (Visual Basic function):
"[Results]
[Comments]"
in two parts:
the results part
the comments part
As you can notice, these two parts are separated by an empty line (always, this is our separator).
[Results] and [Comments] are blocks of text. We don't care what's in it except:
the results part doesn't have any empty lines in it, so the first empty line we see is the separator one.
I want my function to extract the Comments part only.
Here is what i tried:
Public Function ExtractComm(txt As String) As String
Dim emptyLine As Integer
txt = Trim(txt)
'emptyLine = first empty line index ??
emptyLine = InStrRev(txt, (Chr(13) + Chr(10)) & (Chr(13) + Chr(10)))
'Comments part = all that is after the empty line ??
ExtractComm = Mid(txt, emptyLine + 4)
End Function
But it doesn't work well.
If I do:
ExtractComm(
"Res1
Res2
Comment1
Comment2"
)
I want to obtain:
"Comment1
Comment2"
but I only obtain Comment2. Any idea to extract the comment part ?
Thanks a lot !
Maybe you need to use InStr instead of InStrRev
InStrRev
Returns the position of the first occurrence of one string within another, starting from the right side of the string.
InStr
Returns an integer specifying the start position of the first occurrence of one string within another.