Verify string as valid C code - python

I would like to verify that a given string is valid C code in the context of
int main() {
double x[3];
<insert code here>;
return EXIT_SUCCESS;
}
Effectively, I would like the verification to
verifyC('x[0]*x[0] + x[1] + 1') // pass
verifyC('x[0]*x[0] + x[1] +') // fail, syntax error
verifyC('x[0]*x[0] + a') // fail, `a` undefined
What would be a good way of verification?

The simplest way would be to just try to compile a small sample program containing the string you want to check.
This way you get your snippet checked by the real C compiler. This will be far easier and much more reliable than trying to implement all the C parsing and checking in the Python program.

Replace all occurrences of your known variables with a numeric constant. In your code, that would be x[0], x[1], and x[2]. Note that in C lots of intermediate whitespace is allowed, even inside variables: x [ 1 ] is valid. (Also: x[01] is valid. x[0x01] is valid. If the array is larger than 8 elements: x[010] is valid and is actually x[8]. 1[x] is valid and is equal to x[1].)
The numerical constant must in itself be valid, and preferably not equal to 0. (Just to prevent a parser stating 1/x[0] is invalid!)
When replacing, insert a single space before and after your constant. This is to prevent a change of x[1]2 to 12. Do not use parentheses! With those, sin x[1] is invalid but its replacement, sin(1), is.
With this, an input string
x[0]*x[0] + x[1] + 1
is translated into
1 * 1 + 1 + 1
which can be validated with regular procedures; see for example Safe expression parser in Python; or, since you don't need to calculate but only validate, write your own.

Related

Solve Equation (String) with Python to every Symbol

I have to solve a equation in python, which i get as a string input. I don't know how many symbols are in the equation or what their signature is. A typical Symbol could be "mm", "cm", "x" or something like this. The function should return some kind of array/json with the solved equation.
Little Example how it should look like:
solve("x/2=4")
>> ["x=8"]
>>
solve("x + 2 = y - 1")
>> ["x=y-3", "y=x+3"]
I tried to use SymPy-Module for this, but I didn't find a way to enter a dynamic string like above. SymPy seems to only accept "hardcoded" Symbols.
Note: String comes from a "sys.argv"-Parameter.
SymPy can parse strings with sympify, but its format for equations is Eq(x/2, 4) instead of x/2 = 4. So a little preprocessing is necessary: surround the string with Eq( ) and replace "=" by a comma.
eq = "x/2=4"
sympy_eq = sympify("Eq(" + eq.replace("=", ",") + ")")
solve(sympy_eq) # [8]
and
eq = "x + 2 = y - 1"
sympy_eq = sympify("Eq(" + eq.replace("=", ",") + ")")
solve(sympy_eq) # [{x: y - 3}]
In the latter case, SymPy picked one of the variables to solve for. To choose which one it should be, you can provide a Symbol:
solve(sympy_eq, Symbol('y')) # [x + 3]
Or, to solve for every symbol:
[solve(sympy_eq, sym, dict=True) for sym in sympy_eq.free_symbols]
returns [[{y: x + 3}], [{x: y - 3}]]. The list is nested because multiple solutions could appear for each symbol. Flatten the nested list if necessary.
The options list=True and dict=True of solve are convenient for enforcing particular forms of output.
The answer is most probably two different parts.
Parsing:
Parsing means turning some input into a usable output, where in your case the input is some string and the output is something, sympy can work with. A simple parsing step for example is turning strings into integers by doing int(your_string). In your case, you should iterate through your string and find variables, units etc. for example by comparing with a dictionary or a list of strings. Parsing arbitrary input is quite hard, so the best idea is starting with a small set of options, e.g. search the string for occurences of typical variable names like x, y and z by comparing with a list variables=['x','y','z'].
Computing
Once the parsing is clean, simply plug everything into your number crunching / solvers used by sympy.
To see how such a system can work if done correctly, you can have a look at wolfram alpha. They do a quite good parsing / natural language processing and try to guess what to do from there.

Python encryption program (ECC)

I'm trying to code an encryption program that will encode a user's Inputed - if that's a word - string. The encryption method is just a basic use of an elliptic curve encryption and I am currently working on the encryption part of the program at the moment before I work on the mathematical, inverse modules etc. Etc. Required for public and private key calculations. Currently I am using the key pub = 5 and a max value (derived from the product of 2 random primes) of 91. This is all the information needed and the word I am testing the encryption on is 'happy'.
So far here is the code.
word = 'happy'
pub = 5
m = 91
for i in range(pub):
if i == 0:
word = word
else:
word = output
for x in word:
a = [(((ord(z)*ord(z))+1)/m) for z in word]
b = [chr(i) for i in a]
c = [str(i) for i in b]
d = ''.join([str(i) for i in c])
output = d
What I am trying to do is encrypt each letter by multiplying the ASCII value it belongs too by itself and then use the chr() function to rejoin the string after a process of adding 1 then dividing by m , thus creating a new word. Then, using that new string, set it as the value of word for the next cycle in the loop, so the process continues until it has finished pub amount of times and encrypted the word. I'm having a lot of difficulties with this and I don't know where to start with explaining the issues. I'm relatively new to Python and any suggestions and/or advice on completing this fast would be very much appreciated. Thank you in advance.
First, check that your math is right. Your formula (z**2 + 1)/m grows quadratically. My understanding of crypto is quite limited, but it doesn't look right to me. It should be some kind of one-to-one mapping from input to output. But it maps several neighboring characters to the same output. Also, the results grow with every round.
You can only convert the integers back to ascii characters for a range up to 256. That's what your error message says. It's proably thrown in the second iteration of your outer for loop.
You probably need to get the value range down to 256 again.
I suppose you miss a crucial part off the algorithm you are trying to implement, maybe some modulo operation.
Also some minor python hints:
You can use the built in power operator **, so you don't have to evaluate ord() twice.
((ord(z) ** 2) + 1) / m
You can do the conversion back to the string in one step like this:
output = ''.join([str(chr(i)) for i in a])

Python: Add character to string an amount of times depending on an int

Ok, I may have totally butchered the phrasing of this question since I can't quite word it but here's what I'm trying to do:
I have a CPU percentage displayed as characters in a string which show up on a display. If the cpu were at 52% I'd want the string to be CPU:[#####] 64% CPU:[######] but 77% CPU:[#######/] etc.
The only method I can thing off is having 20 if statements each with their own version of the string which shows dependant on the int percentage's value. I feel this would be a horrible way of doing it and wanted to know if there is a better way I can do this?
Assuming you want the number of hashes to be the “tens digit” of the CPU percentage, this simple function will do it:
def cpu_usage_str(cpu_percentage):
return 'CPU:[%s]' % ('#' * cpu_percentage / 10)
print cpu_usage_str(52)
print cpu_usage_str(64)
print cpu_usage_str(72)
(This assumes Python 2, with floor division. You’d need to tweak it slightly for Python 3.) We use the * operator to repeat the '#' string the appropriate number of times.
output:
CPU:[#####]
CPU:[######]
CPU:[#######]
Alternatively, if you’d like to round to the nearest ten (so 36% becomes CPU:[####], say), then this will do the trick:
def alt_cpu_usage_str(cpu_percentage):
return 'CPU:[%s]' % ('#' * int(round(cpu_percentage / 10.0)))
First we divide by 10.0 to get a float between 0.0 and 10.0. Then round takes us to the nearest whole number. This is represented by a float, so we convert it to an int and then repeat the string as before.
If we want a backslash to indicate whether we're under/over 5, then we need to consider cpu_percentage % 10 (the % is the modulo operator). Here's a function which does it:
def with_slashes_cpu_usage_str(cpu_percentage):
hashes_str = '#' * int(round(cpu_percentage / 10))
slash_str = '/' * (cpu_percentage % 10 >= 5)
return 'CPU:[{hash}{slash}]'.format(hash=hashes_str, slash=slash_str)
We construct the hash and slash strings separately. The bool cpu_percentage % 10 >= 5 is coerced to 0 or 1, which gives us the slash, or not, depending on whether or not we're in the upper half of that 10.
If you want [ ]5% not to print that trailing slash, then change to a strict inequality.
You can repeat a string using *, e.g. '#'*5 gives '#####'
print "CPU:[%s]"%('#'*(percentage/10))

Python - String of Digits to Integer using Recursion?

Say I have a string = '123' but I want to convert it into 123 without using the int() function. How would I go upon doing this using recursion?
The idea I have so far is to put the string into an array as such ['1','2','3'] and then convert them based on ASCII representations.
for i in string:
myArr.append (ord(i) - ord('0'))
So now I'd have a list looking like [1,2,3]. What should I do next to recursively get 123?
I have an idea of using the place values and add them together (ie. 100 + 20 + 3 = 123), but I don't know how to do this. Any ideas would be helpful !
I guess this is an academic exercise, because it's a rather contrived thing to ask. Here's how, assuming that s represents an integer number greater than or equal to zero:
def strToInt(s, acc):
if not s:
return acc
return strToInt(s[1:], 10 * acc + ord(s[0]) - 48)
Or even shorter:
def strToInt(s, acc):
return strToInt(s[1:], 10 * acc + ord(s[0]) - 48) if s else acc
The trick is to accumulate the result of the conversion in an extra parameter, this has the nice side effect of yielding a tail-recursive solution (not that it matters much in Python, but still…). Also notice how we use ord() to get the numeric value of a character representing a digit, and by simply subtracting 48 we get to the actual digit's value. Test it, it works as expected:
strToInt('123', 0) # the accumulator always starts in zero
=> 123
This wouldn't be recursive (I don't think you understand what that means), but:
for char in string:
array.append(ord(char) - ord('0'))
array.reverse()
num = 0
for index, val in enumerate(array):
num += val * (10 ** index)
EDIT: Ah, I see this is for an exercise. Yeah, it's a ridiculous problem to solve via recursion, but one of the other answers does it.
Another possibility:
def strToInt(s):
if s:
return (ord(s[-1]) - ord('0')) + 10 * strToInt(s[:-1])
else:
return 0
The first thing that comes to mind is the famous C method atoi().
Python had a similar method, also called atoi(), but it was deprecated, with the instruction to use int().
Therefore, despite your comment, I would recommend using int(). Python documentation encourages you to use it, so do so without fear.
int() documentation for Python 2.7
int() documentation for Python 3.3

Parsing string to see if it can be cast to a float

Part of my homework assignment is to write a function that will parse a string such as '-.4e-4' and identify any problems that would prevent it from being cast to a float. For example, in '10e4.5' I would need to detect the decimal in the exponent and provide a relevant error message.
I have attempted many things. The first and, of course, most basic is the try: except:. Attempt to cast it to a float and let Python do the heavy lifting. However, as far as I can see, the errors it can return are not descriptive enough for this assignment.
The second thing I tried was to normalize the string, replacing all digits with n, signs with s, decimals with d, exponents with e (the maketrans function from C made this very fast). Then, I cut down any repeated n's to a single n. I made a list of all valid float formats and checked if the normalized string was in that list. AKA, I white-listed it. It worked perfectly and rather time-efficiently, but again, no error checking. That code is posted below.
import string,time
check_float_trans = string.maketrans("nsd0123456789-+.","???nnnnnnnnnnssd")
check_float_valids = 'n sn sndn ndn ndnen dn sdn sdnen sdnesn dnesn dnen nen nesn snesn sn snen sndnen sndnesn ndnesn'.split()
def check_float( test ):
"""Check if string <test> could be cast as a float, returns boolean."""
test = test.translate(check_float_trans)
test = ''.join([a for a,b in zip(test, ' '+test) if a != b])
return test in check_float_valids
I was hoping someone here could give me some pointers. I don't want this handed to me, but I am relatively stuck. I tried guardian-coding it, trying to identify reasons why the string might not be castable as a float, but I could never put up enough walls to ensure that no bad strings got a false positive.
Thanks.
Here's what I would do... (also this is untested)
def isValid(expression):
if 'e' in expression:
number, exponent = expression.split('e')
else:
print "not a valid format, no 'e' in expression"
return False
# a bunch of other if statments here to check for
#certain conditions like '.' in the exponent component
return float(number) ** float(exponent)
if __name__ == '__main__':
print isValid('-.4e-4')
print isValid('10e4.5')

Categories