Python Forum

Full Version: Embedding python script into html via pyscript
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi everyone,
I want to embed a python script into an html page by using pyscript. What I am trying is giving a sequence of integers as "1,2,3,4,5,6" and another integer "n" which divides the length of the sequence as inputs, the python script gives a matrix. Here is what I have tried:
<html>
  <head>
    <link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
    <script defer src="https://pyscript.net/latest/pyscript.js"></script>
  </head>
  <body>

    <input type="text" id="input_str"/>
    <input type="number" id="n"/>
    <button id="submit-button" type="button" py-click="my_function()">OK</button>
    <div id="test-output"></div>

    <p>Output:</p>
    <p id='output'></p>

    <py-config>
      packages = ["numpy"]
    </py-config>

    <py-script>
	import numpy as np
	from pyscript import Element

	def my_function():
		input_str = Element('input.str').value
		n = int(Element('n').value)

    input_list = input_str.split(",")
    w = []
    for num in input_list:
      w.append(int(num))
	
		rows = len(w) // n
		A = np.zeros((rows, n))

    for i in range(len(w)):
      if (w[i] % n == 0):
        A[w[i]//n - 1, n-1] = int(i+1)
    else:
        A[w[i]//n, w[i]%n-1] = int(i+1)

		result_place = Element('output')
		result_place.write(str(A))

    </py-script>
  </body>
</html>
The python script works well alone, however, it gives the following error when I try to compile the html file.

Error:
IndentationError: unindent does not match any outer indentation level
Any help would be appreciated to fix it.
Pyscript examples show the python code indenented. Yours is at the same level as the html tags.
I have updated the code as follows:
<html>
  <head>
    <link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
    <script defer src="https://pyscript.net/latest/pyscript.js"></script>
  </head>
  <body>
 
    <input type="text" id="input_str"/>
    <input type="number" id="n"/>
    <button id="submit-button" type="button" py-click="my_function()">OK</button>
    <div id="test-output"></div>
 
    <p>Output:</p>
    <p id='output'></p>
 
    <py-config>
      packages = ["numpy"]
    </py-config>
 
    <py-script>
    import numpy as np
    from pyscript import Element
 
    def my_function():
        input_str = Element('input_str').value
        n = int(Element('n').value)
 
    input_list = input_str.split(",")
    w = []
    for num in input_list:
      w.append(int(num))
     
    rows = len(w) // n
    A = np.zeros((rows, n))
 
    for i in range(len(w)):
      if (w[i] % n == 0):
        A[w[i]//n - 1, n-1] = int(i+1)
    else:
        A[w[i]//n, w[i]%n-1] = int(i+1)
 
        result_place = Element('output')
        result_place.write(str(A))
 
    </py-script>
  </body>
</html>
However, now it gives the following error message:

Error:
NameError: name 'input_str' is not defined
Any ideas to fix it?
You don't have a variable named input_str assigned outside my_function().
    def my_function():
        input_str = Element('input.str').value  # Assigned inside function
        n = int(Element('n').value)
 
    input_list = input_str.split(",")  #  Never assigned out here
Is this an indentation error?
for i in range(len(w)):
    if (w[i] % n == 0):
    A[w[i]//n - 1, n-1] = int(i+1)
else:
    A[w[i]//n, w[i]%n-1] = int(i+1)

    result_place = Element('output')   # Should these lines be same depth as else?
    result_place.write(str(A))
I have edited the code as follows
    def my_function():
        input_str = Element('input_str').value
        n = int(Element('n').value)
        input_list = input_str.split(",")
        w = []
and now it gives the error:
Error:
NameError: name 'input_list' is not defined
Any suggestion?
The name was not thr problem. This is a scope problem. Do you know about python variable scope?

A variable assignment inside a function creates a variable that is only visible inside the function. Outside the function the variable does not exist. Outside the function is "outside" the scope of the variable.

You could tell python to create the variable in the global scope like this:
    def my_function():
        global input_str
        input_str = Element('input_str').value
        n = int(Element('n').value)
But this wouldn't work for you either since you have to call a function to execute the code, and the input_str variable does not exist until it is assigned (when the function executes).

Using global variables should be avoided. Global variables make it easier to create bugs and makes it harder to find those bugs. Instead of using a global variable to return a value from a function, use the "return" statement.

Let's say the purpose of my_function() is to get the values for inputs "input_str" and "n". I would write the function like this:
def get_inputs():   # Name functions for what they do or what they return.
    """Get values for inputs_str and n."""    #  Use a docstring to describe what the function does
    input_str = Element('input_str').value
    n = int(Element('n').value)
    return input_str, n
Somewhere in you script you would call the function like this:
input_str, n = get_inputs()
You would call the function before you using input_str or n.
Could fix the scope problem to move all code into my_function().
Quick test,code now work to code that's comment out.
Input 1,2,4 and 4 then press OK.
<html>
  <head>
    <link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
    <script defer src="https://pyscript.net/latest/pyscript.js"></script>
  </head>
  <body>

    <input type="text" id="input_str"/>
    <input type="number" id="n"/>
    <button id="submit-button" type="button" py-click="my_function()">OK</button>
    <div id="test-output"></div>

    <p>Output:</p>
    <p id='output'></p>

    <py-config>
      packages = ["numpy"]
    </py-config>

    <py-script>
    import numpy as np
    from pyscript import Element

    def my_function():
        input_str = Element('input_str').value
        print(input_str)
        n = int(Element('n').value)
        print(n)
        input_list = input_str.split(",")
        w = []
        for num in input_list:
            w.append(int(num))
        print(w)
        rows = len(w) // n

        A = np.zeros((rows, n))
        for i in range(len(w)):
            print(i)
        '''
            if (w[i] % n == 0):
                A[w[i]//n - 1, n-1] = int(i+1)
            else:
                A[w[i]//n, w[i]%n-1] = int(i+1)
            result_place = Element('output')
            result_place.write(str(A))'''

    </py-script>
  </body>
</html>
So the HTML calls work and now the problem is just a Python code problem between line 40-45.
@deanhystad, thanks for this detailed great answer.

@snippsat, thank you so much, it worked like a charm.