Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am trying to program a calculator which allows users to input an equation and receive an answer (order of operations apply). I will not be using the input() command to gather user input, but rather the raw_input() command. I heard from another user that I could accomplish this task with the help of recursive parsing, I quote:
"The first step would be separating the string into each argument.
Let's say that the user inputs:
1+2.0+3+4
Before you can even convert to ints, you are going to need to split the string up into its components:
1
+
2.0
+
3
+
4
This will require a recursive parser..." -aong152
Additionally, I read this article which explains how recursive parsing might be used to produce the results I am looking for:
http://blog.erezsh.com/how-to-write-a-calculator-in-70-python-lines-by-writing-a-recursive-descent-parser/
I do not understand the coding that the author uses, and I have searched on this website and on Google for help in beginning to learn recursive parsing, but I cannot find anything. Can anyone give me a push in the right direction and explain the basics of recursive parsing to me?
Recursive parsing of simple arithmetic summations can be fairly easily analogized into adding a lot of brackets. A recursive parser might parse the above summation like this: 1+(2.0+(3+(4))). The reason for this is that you want to break the whole thing down into individual units of work that can be computed. This means each part must contain at most two numbers and one operator (the base case for the recursion would be a single number).
Each pair of brackets is added by an additional level of recursion (the function calling itself). So, the initial call sees something like "1 plus some complex stuff the next level of recursion will take care of for me".
When the base case is not yet reached, each call will parse the first number and the operation. Then, it will call itself on the next part of the string after the operation, and return the results of the operator for its digit and that next call (eg. something like return number + parse(string[length:])).
When the base case is reached (only one number is left in the string), instead of returning something depending on another function call, it will just return the number. Then, the recursion unwinds, with each function getting the value of the complex right hand side. Eventually, the original call will return the result.
This is fairly easily extended to allow for other operators by having each instance of the function work on an operator (instead of an operator and a number), and the expression to the left and right of it, starting with the highest-precedence operator. So, when parsing a string like 0+1+2*3+4, you must start with the multiplication. Your function, returning something like function(left-hand-side) operator function(right-hand-side), would initially parse it like this: (0+1+2)*(3+4). This would turn into (0+(1+(2)))*(3+(4)). You can parse linearly along operators with the same precedence, so the algorithm can iterate looking for multiplication or division to recurse on, recursing on the first one found; if none is found it can do the same for addition and subtraction, and finally if none is found just return the number as the base case (interestingly, the latter example I gave has 2 base case instances, 2 and 4; this is a feature of multiple recursion).
A fully working parser using pyparsing that can handle +-/* can be found here:
http://pyparsing.wikispaces.com/file/view/fourFn.py/30154950/fourFn.py
This uses a recursive grammar to handle the proper nesting of parenthesis. It may be worth working through the examples in the book, you'll learn to write a grammar and how it's something different from a parser!
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I am trying to detect if a string contains any element in an array. I want to know if the string(msg) has any element from the array(prefixes) in it.
I want this because I want to make a discord bot with multiple prefixes, heres my garbage if statement.
if msg.startswith(prefixes[any]):
The existing answers show two ways of doing a linear search, and this is probably your best choice.
If you need something more scalable (ie, you have a lot of potential prefixes, they're very long, and/or you need to scan very frequently) then you could write a prefix tree. That's the canonical search structure for this problem, but it's obviously a lot more work and you still need to profile to see if it's really worthwhile for your data.
Try something like this:
prefixes = ('a','b','i')
if msg.startswith(prefixes):
The prefixes must be tuple because startswith function does not supports lists as a parameter.
There are algorithms for such a search, however, a functional implementation in Python may look like this:
prefixes = ['foo', 'bar']
string = 'foobar'
result = any(map(lambda x: string.startswith(x), prefixes))
If you search for x at any position in string, then change string.startswith(x) to x in string.
UPDATE
According to #MisterMiyagi in comments, the following is a more readable (possibly more efficient) statement:
result = any(string.startswith(prefix) for prefix in prefixes)
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Should I create variables just to avoid having long lines of code? For example, in the code below the variable stream_records is only used once after it's set.
stream_records = stream.get_latest_records( num_records_to_correlate ).values('value')
stream_values = [float(record['value']) for record in stream_records]
Should I have done this instead?
stream_values = [float(record['value']) for record in stream.get_latest_records( num_records_to_correlate ).values('value')]
I am trying to optimize for readability. I'd love some opinions on whether it's harder to have to remember lots of variable names or harder to read long lines of code.
EDIT:
Another interesting option to consider for readability (thanks to John Smith Optional):
stream_values = [
float(record['value'])
for record in stream.get_latest_records(
num_records_to_correlate
).values('value')
]
PEP 8 is the style guideline from the beginning of Python, and it recommends that no source lines be longer than 79 characters.
Using a variable for intermediate results also performs a kind of documentation, if you do your variable naming well.
Newlines (carriage return) inside parentheses count as blank.
The same applies to newlines inside brackets, as pointed out by Bas Swinckels.
So you could do something like that:
stream_values = [
float(record['value'])
for record in stream.get_latest_records(
num_records_to_correlate
).values('value')
]
You can also use \ to continue a statement on the following line.
For example:
long_variable_name = object1.attribute1.method1(arg1, arg2, arg3) + \
object2.attribute2.method2(arg1, arg2, arg3)
the first one is definitely easier to read so if there are no performance concerns I would totally go for more variables as long as they have self-explanatory names. it's also way easier to debug if somebody (not you) has to.
The first one is indeed more readable. Creating a variable doesn't cost you a lot here, so you can leave your code with it. Plus, if you are debugging it, it will be much easier to see if the error comes from the call of get_latests_records or from your list comprehension.
However, another way nice way would be to construct your list with the map function:
stream_values = map(lambda x: float(x['value']),
stream.get_latest_records(num_records_to_correlate) \
.values('value')])
The lambda here is necessary, to apply float on the correct value of the dictionary. As you can see, I have limited the number of chars per line to respect the PEP8 convention, which can help to make the code readable too.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 9 years ago.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Improve this question
I have a data set as follows it includes some negative values. I have written codes to read those values. But when any negative numbers percent. It gives error. File format is as below
1SOL HW1 2 1.4788 2.7853 -0.7702
1SOL HW2 3 1.4640 -2.8230 0.6243
2SOL OW 4 -1.5210 0.9510 -2.2050
2SOL HW1 5 1.5960 -0.9780 2.1520
I have written code as follow. I am using for loop and if function to select P[3], P[4], P[5] positions.
X=[]
P = line.split()
x = float(P[3]) `#then I collect these numbers in to array like X = []`
X.append(x)
This code work if there is no negative values.
Then I used following function to write X in to another file. But it is not working
A.write('%s\n' % (X)) `# this is not working since it X is Float. File open as A to write`
Please some one help me to correct my cords.
The reason A.write('%s\n' % (X)) doesn't work has nothing to do with X being a float.
There may be a problem in that (X) isn't a tuple of one float as you seem to expect, it's just a float. Commas make a tuple, not parentheses. In particular, comma-separated values anywhere that they don't have some other meaning (function arguments, list members, etc.) are a tuple. The parentheses are only there to disambiguate a tuple when the comma-separated values would otherwise have another meaning. This is usually simple and intuitive, but it means that in the case of a one-element tuple, you need to write (X,).
However, even that shouldn't be a problem: '%s\n' % 3.2 is '3.2\n'.
On top of that, X isn't actually a float in the first place, it's a list. You explicitly created it as X = [], and then appended each float to it. Again, that's not a problem, but it means you're possibly not getting the output you wanted. This is just a guess, since you never explained what output you wanted or what you were actually getting. But '%s\n' % [3.2, 3.4] is '[3.2, 3.4]\n'. If you wanted each one on a separate line, you have to loop over them, explicitly or implicitly—maybe ''.join('%s\n' % x for x in X).
As for why your negative numbers don't work, there are many possibilities, and it's impossible to guess which without more information, but here are some examples:
There is something that Python (more specifically, split()) considers whitespace, even if it doesn't look like it to you, between the - and the numbers. So, you're trying to convert "-" to a float rather than "-12345".
Those apparent - characters are actually a Unicode minus rather than a hyphen, or something else that looks similar. .decode-ing the file with the right encoding might solve it, but it might not be enough.
There are invisible, non-spacing characters between the - and the first digit. Maybe Unicode again, or maybe just a control character.
In many cases, the exception string (which you didn't show us) will show the repr of the string, which may reveal this information. If not, you can print repr(P[3]) explicitly. If that still doesn't help, try print binascii.hexlify(P[3]) (you'll have to import binascii first, of course).
It's impossible to tell what will work because we can't see your source file, but the problem you're having is with your split function. If I were you, I'd try P = line.split('\t') and see if that resolves your issue.
This question already has an answer here:
Splitting an input in to fragments (Python)
(1 answer)
Closed 9 years ago.
I need to somehow convert a mathematical input(str) to a number,
e.g.
4-3*2-1+5 = ((((4-3)*2)-1)+5).
Current code looks like this:
Answer = input ('Put your answer here: ')
4-3*2-1+5
Somehow, I need to remake the string in to smaller fragments so that it reads from left to right, and to remake the numbers in to integers, but I have no idea how to do it.
I tried doing
Answer.split('+','-','*','/')
But it says TypeError: split() takes at most 2 arguments (4 given)
Also tried adding the answer to a list to see if that helped me at all:
li.append(Answer)
(li = ['4-3*2-1+5']
But I don't see anything beneficial with that..
Please help!
(I'm new to SOF, so if there's any information that's missing, please tell me what and I will try to correct it).
What you need to write is a parser and simple evaulator for simple expressions.
I would start reading any of the following:
http://pyparsing.wikispaces.com/HowToUsePyparsing
http://pyparsing.wikispaces.com/Examples
http://kmkeen.com/funcparserlib/
There are many other parser libraires, but these are just a couple.
You could also just use the rply library which if you have a look at the PyPi page has an example that directly implement and simple expression parser and evaluater just like what you're describing in your question.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
the following problem in python please .....
Assuming that s is a string of lower case characters.
how would I write a program that prints the number of times the string 'bob' occurs in s. For example, if s = 'azcbobobegghakl', then my program would print
'Number of times bob occurs is: 2'
I am a completely new to python and appreciate any help
If you didn't want to count overlapping bobs as separate values, this would be easy:
s.count('bob')
But you apparently do. (I had to guess that, based on the fact that your intended output is 2 rather than 1… in the future, it would be better to explain your problem instead of leaving it ambiguous.) As the help says, count returns "the number of non-overlapping occurrences of substring sub…", so that won't do any good.
So, for that, you will have to do it manually. I'll show an example that should have enough to get you started:
for i in range(len(s)):
if s[i:].startswith('bob'):
print('Found a bob')
A slightly smarter way to do this would be to use the find method on strings. You can find details on this in the online docs, or by typing help(str.find) in the interactive console. Notice that find takes a start argument. You should be able to figure out how this would help you; it may take a bit of work to get the details right, but if you get stuck, you can always post a new question asking for specific help.
You can try this way
string = "BOBOBOBOBOABCDE"
search = "BOB"
print len([i for i in range(len(string)) if string.startswith(search, i)])