0

This script has a formula where at the beginning the numbers x1 and x2 in the code are set, and I need to change the code so that the value x1 is taken from the list pre-prepared text document For example, from a document: 'List.txt'

That is, it turns out I need to enter:

with open ("List.txt '", "r") as f:

into place the value x1 = 6 in the code. But how to systematize it? Just not very rich in knowledge of Python.

List of numbers:

1
4
2
15
6
8
13
3
12
5
10
7
14
9
11

Code: (Powered by Python 2.7)

import sys

a=0
b=7
p=37

x1=6
x2=8

if (len(sys.argv)>1):
    x1=int(sys.argv[1])
if (len(sys.argv)>2):
    x2=int(sys.argv[2])
if (len(sys.argv)>3):
    p=int(sys.argv[3])
if (len(sys.argv)>4):
    a=int(sys.argv[4])
if (len(sys.argv)>5):
    b=int(sys.argv[5])


def modular_sqrt(a, p):
    """ Find a quadratic residue (mod p) of 'a'. p
        must be an odd prime.

        Solve the congruence of the form:
            x^2 = a (mod p)
        And returns x. Note that p - x is also a root.

        0 is returned is no square root exists for
        these a and p.

        The Tonelli-Shanks algorithm is used (except
        for some simple cases in which the solution
        is known from an identity). This algorithm
        runs in polynomial time (unless the
        generalized Riemann hypothesis is false).
    """
    # Simple cases
    #

    if legendre_symbol(a, p) != 1:
        return 0
    elif a == 0:
        return 0
    elif p == 2:
        return p
    elif p % 4 == 3:
        return pow(a, (p + 1) / 4, p)

    # Partition p-1 to s * 2^e for an odd s (i.e.
    # reduce all the powers of 2 from p-1)
    #
    s = p - 1
    e = 0
    while s % 2 == 0:
        s /= 2
        e += 1

    # Find some 'n' with a legendre symbol n|p = -1.
    # Shouldn't take long.
    #
    n = 2
    while legendre_symbol(n, p) != -1:
        n += 1

    x = pow(a, (s + 1) / 2, p)
    b = pow(a, s, p)
    g = pow(n, s, p)
    r = e

    while True:
        t = b
        m = 0
        for m in xrange(r):
            if t == 1:
                break
            t = pow(t, 2, p)

        if m == 0:
            return x

        gs = pow(g, 2 ** (r - m - 1), p)
        g = (gs * gs) % p
        x = (x * gs) % p
        b = (b * g) % p
        r = m


def legendre_symbol(a, p):
    """ Compute the Legendre symbol a|p using
        Euler's criterion. p is a prime, a is
        relatively prime to p (if p divides
        a, then a|p = 0)


        Returns 1 if a has a square root modulo
        p, -1 otherwise.
    """
    ls = pow(a, (p - 1) / 2, p)
    return -1 if ls == p - 1 else ls

def egcd(a, b):
    if a == 0:
        return (b, 0, 1)
    else:
        g, y, x = egcd(b % a, a)
        return (g, x - (b // a) * y, y)

def modinv(a, m):
    g, x, y = egcd(a, m)
    if g != 1:
        print ("x")
    else: 
       return x % m


print "a=",a
print "b=",b
print "p=",p

print "x-point=",x1
print "x-point=",x2


z=(x1**3 + a*x1 +b) % p
y1=modular_sqrt(z, p)

z=(x2**3 + a*x2 +b) % p
y2=modular_sqrt(z, p)

print "\nP1\t(%d,%d)" % (x1,y1)
print "P2\t(%d,%d)" % (x2,y2)



s=((-y2)-y1)* modinv(x2-x1,p) 

x3=(s**2-x2-x1) % p

y3=((s*(x2-x3)+y2)) % p

result =  "Q\t(%d,%d)" % (x3,y3)
f = open('Result01.txt', 'w')
f.write(result)
f.close()

Earlier, I saw scripts where numbers are taken from one text document, perform a function, and the result is saved in another text document.

Izi Tors
  • 3
  • 3
  • If you are only just learning the basics, you should probably ignore Python 2, and spend your time on the currently recommended and supported version of the language, which is Python 3. – tripleee Feb 09 '20 at 11:50
  • Requiring command-line arguments in a specific order becomes problematic when you have more than two or three. A better solution is to implement a simple command-line option parser. If it makes sense for your application, provide sensible defaults so that the user won't have to specify everything every time (after all, options should be optional). The `ArgParse` library is included with Python 2.7, but is also available in Python 3. The documentation includes a [tutorial](https://docs.python.org/2/howto/argparse.html) for getting started. – tripleee Feb 09 '20 at 12:09

3 Answers3

0

Try using the pandas library to read, process and write your numbers.

import pandas as pd    # import pandas module and call it pd for short
x2 = 6                 
df = pd.read_csv('input_file.txt')    # read the data from a text file into a dataframe
df['x1 times x2'] = df['x1'] * x2     # create new column in your dataframe with result of your function
df.to_csv('output_file.txt', index=False)    # output result of your calculations (dropping the dataframe index column)
TaxpayersMoney
  • 669
  • 1
  • 8
  • 26
  • 2
    Pandas is complete overkill here. Unless you are already using it for more complex tasks, or plan specifically to learn Pandas, I would not recommend this approach. – tripleee Feb 09 '20 at 11:52
0

Although you're hard coding the values of x1, x2, in your code, they can be redefined, as you're doing here:

if (len(sys.argv)>1):
    x1=int(sys.argv[1])
if (len(sys.argv)>2):
    x2=int(sys.argv[2])

So if you call your script from command line, like C:\Users\test.py x1value x2value you can redefine x1 and x2. If you really want a text file to contain your x1 and x2, just use the following snippet somewhere at the top

import json
with open("input.json","r",encoding="utf-8") as stream:
    parsed = json.load(stream)
    x1,x2 = parsed["x1"],parsed["x2"]

Contents of "input.json":

{"x1":1,"x2"=2}
kleerofski
  • 423
  • 4
  • 8
0

With only python without extra dependencies, your can read List.txt as follow

with open("List.txt","r") as f:
    arrX1 = list(map(int,f.readlines()))

print (arrX1)

The above reads all the lines in f and converts/maps them to integers. The list function then gives you an array you can loop through to generate x2 and write to the Result.txt file.

The above prints

[1, 4, 2, 15, 6, 8, 13, 5, 3, 10, 7, 14, 9, 11]

So for your code replace all lines from 125 downward with

# Read numbers from file and put them in an array
with open("List.txt","r") as f:
    arrX1 = list(map(int,f.readlines()))
f.close()

# Open the result file to write to
f = open('Result01.txt', 'w')

# Now get x1 for each item in the list of numbers from the file
# then do the calculations
# and write the result
for x1 in arrX1:
    z=(x1**3 + a*x1 +b) % p
    y1=modular_sqrt(z, p)

    z=(x2**3 + a*x2 +b) % p
    y2=modular_sqrt(z, p)

    print "\nP1\t(%d,%d)" % (x1,y1)
    print "P2\t(%d,%d)" % (x2,y2)

    s=((-y2)-y1)* modinv(x2-x1,p) 

    x3=(s**2-x2-x1) % p

    y3=((s*(x2-x3)+y2)) % p

    result =  "Q\t(%d,%d)" % (x3,y3)
    f.write(result)

f.close()
  • I get an error: Traceback (most recent call last): File "D:\test.py", line 129, in z=(x1**3 + a*x1 +b) % p TypeError: unsupported operand type(s) for ** or pow(): 'list' and 'int' >>> – Izi Tors Feb 09 '20 at 16:02
  • Are you looping through the x1's in the arrX1? i.e. `for x1 in arrX1: ; ` – Jacques Verryn Feb 09 '20 at 16:29
  • This code only works on Python 2.7. I again get an error on the characters <> Where exactly should this be written: for x1 in arrX1: ; – Izi Tors Feb 09 '20 at 16:42
  • With and , I was referring to the code you current have in line 126 onwards. I'm adding code into my answer above that you can try as is. – Jacques Verryn Feb 09 '20 at 20:22
  • I run the code, but as a result from the file: List.txt takes only the last value. I need your function to take each number sequentially, process it and write it to a file: Result01.txt At the moment, your function takes only the last number, and the rest are not included ((Why don't I understand? Here is the code: https://pastebin.com/yj3nsWK0 Powered by Python 2.7 – Izi Tors Feb 09 '20 at 22:26
  • You should also indent lines 147 to 154 into the for loop else they only execute once at the end of the for loop, thus you only see it working for the last value in the file. Importantly the last code line with f.close() should not be indented. – Jacques Verryn Feb 10 '20 at 03:29
  • I also want to use large numbers in the HEX format, but unfortunately I get this error: Traceback (most recent call last): File "E:/003.py", line 126, in arrX1 = list(map(int,f.readlines())) ValueError: invalid literal for int() with base 10: '0x38d1\n' Please help, what do I need to fix? – Izi Tors Feb 10 '20 at 06:52
  • Add a new function `def hexint(i): return int(i,0)` then pass that into the map function. i.e. on line 126 do `arrX1 = list(map(hexint,f.readlines()))`. You can look at [this](https://stackoverflow.com/questions/209513/convert-hex-string-to-int-in-python) for a bit of background on why you are getting the error. – Jacques Verryn Feb 10 '20 at 08:01
  • With hexint (i), it worked! But here another error occurs when when performing calculations according to the formula "s =" the value becomes negative, the script stops. Is it possible to make the script skip this error when an error occurs and don’t stop following the other other sequential commands? – Izi Tors Feb 10 '20 at 08:21
  • This error appears. That is, the script stops. Is it possible to ignore this stop? Traceback (most recent call last):    File "E: \ 003.py", line 148, in      s = ((- y2) -y1) * modinv (x2-x1, p) TypeError: unsupported operand type (s) for *: 'long' and 'NoneType' >>> – Izi Tors Feb 10 '20 at 09:22
  • Have a look at python exception handling. You can wrap the line in a try except. A better way of doing it would be to check your values an handle the negative case properly. If you have further issues, I'd suggest you ask a new question seeing as these comments are getting off topic from your original question. – Jacques Verryn Feb 10 '20 at 10:15