Python global list not being updated - python

I have a global list and it seems that it doesn't update the list in the file it is declared. I have seen several question similar to my issue which I can use to fix my issue. But I was trying to understand why it does not work in my case.
HelloWorld.py
import TestFile
store_val = ["10", "20"]
def main():
store_val.append("30")
print store_val
TestFile.list_val()
if __name__ == '__main__':
main()
TestFile.py
import HelloWorld
def list_val():
HelloWorld.store_val.append("40")
print "Store Value : ", HelloWorld.store_val
HelloWorld.store_val.append("60")
print "Updated Value : ", HelloWorld.store_val
The problem that I see is that I am able to append a value to the list in TestFile.py but can't seem to add a value to the list in HelloWorld.py even though it is declared there. What is the best way to rectify this issue so that I can append the value from HelloWorld.py
Result of running HelloWorld
['10', '20', '30']
Store Value : ['10', '20', '40']
Updated Value : ['10', '20', '40', '60']

Should be this way instead . In your case only the store_val list and main function gets imported from HelloWorld in TestFile.py but the main function is not run in TestFile.py
HelloWorld.py
import TestFile
store_val = ["10", "20"]
def main(n=1):
store_val.append("30")
print store_val
if n>0:
TestFile.list_val(n)
if __name__ == '__main__':
main()
TestFile.py
import HelloWorld
def list_val(n):
if (n>=0):
HelloWorld.main(n-1)
HelloWorld.store_val.append("40")
print "Store Value : ", HelloWorld.store_val
HelloWorld.store_val.append("60")
print "Updated Value : ", HelloWorld.store_val
if __name__ == '__main__':
list_val()
Run Code:
python HelloWorld.py
['10', '20', '30']
['10', '20', '30']
Store Value : ['10', '20', '30', '40']
Updated Value : ['10', '20', '30', '40', '60']

Related

passing array list to python argument

trying to pass an array list of ec2 instance ids to my python script
#!/usr/bin/env python3
import boto3
import sys
import argparse
instance_id = list(sys.argv[1])
#aws_region = sys.argv[2]
tagname = sys.argv[2]
tagvalue = sys.argv[3]
EC2_RESOURCE = boto3.resource('ec2', region_name='us-west-1')
def tag_instance(instance_id,tagname,tagvalue):
TAGS = [
{
'Key': tagname,
'Value': tagvalue
}
]
instances = EC2_RESOURCE.instances.filter(
InstanceIds=[
instance_id,
],
)
for instance in instances:
instance.create_tags(Tags=TAGS)
print(f'Tags successfully added to the instance {instance.id}')
tag_instance(instance_id,tagname,tagvalue)
but keep getting this error
Invalid type for parameter InstanceIds[0],
value: ['i', '-', '0', '9', '2', 'b', 'b', 'a', 'b', 'a',
'f', '1', 'e', '8', '2', 'f', '5', 'a', '1', ','],
type: <class 'list'>,
valid types: <class 'str'>
any ideas?
Looking at the error, the comma at the end of the instance name strikes me. I assume, you make some incorrect assumptions on how the command line is parsed.
Try the following. Change the following lines in your script:
instance_ids = sys.argv[1].split(",")
and
instances = EC2_RESOURCE.instances.filter(InstanceIds=instance_ids)
Then call the script as:
scriptname "instance1,instance2,instance3" tagname tagvalue
Alternatively, you can move tagname and tagvalue to position 1 and 2 and use position 3.. for the instance names:
tagname = sys.argv[1]
tagvalue = sys.argv[2]
instance_ids = sys.argv[3:]
Then call it:
scriptname tagname tagvalue instance1 instance2 instance3
A different point: Your print statement is indented incorrectly, it will only be executed after the loop. Correct your code as follows:
for instance in instances:
instance.create_tags(Tags=TAGS)
print(f'Tags successfully added to the instance {instance.id}')

List to string with separators

I am trying to pass a command line arguments to AWS lambda as a event json.
I have a list out of the command line args like:
['engine', '-e', '100', '-w', '4']
When I pass this list I want to it get passed as:
'engine', '-e', '100', '-w', '4'
I am trying to use it like this:
listcommd = ['engine', '-e', '100', '-w', '4']
command = ["--bucket", "mybucket", f"{listcommand}"]
I want the end result to look like:
command = ["--bucket", "mybucket", 'engine', '-e', '100', '-w', '4']
but it is looking like:
command = ["--bucket", "mybucket", "['engine', '-e', '100', '-w', '4']"]
Lists support concatenation. Just do this:
command = ["--bucket", "mybucket"] + listcommand

How to show data from other function into flask app

I am new to python and flask. Can anyone help me on this
from flask import Flask
import logging
logging.basicConfig(filename="err.log",level=logging.DEBUG)
student = ['abcd', '001', '11'] # I want to extract list value from here and needs to display in flask app
app = Flask(__name__)
#app.route("/")
def student_details():
print("student: "+student[0])
print("id: "+student[1])
print("grade: "+student[2])
student_details()
if __name__ == "__main__":
app.run(host='127.0.0.1', port="8000",debug=False)
Current Output: Internal Server Error
Desired Output:
student: abcd
id: 001
grade: 11
Although I would suggest reading about how to make html pages and use Jinja templates with flask, Use return instead of print. print() is used for printing on the console. You can also use a for loop to generate a string and then return it.
from flask import Flask
import logging
logging.basicConfig(filename="err.log",level=logging.DEBUG)
student = ['abcd', '001', '11'] # I want to extract list value from here and needs to display in flask app
app = Flask(__name__)
#app.route("/")
def student_details():
return "student " + str(student[0]) + " id " + str(student[1]) + " grade " + str(student[2])
if __name__ == "__main__":
app.run(host='127.0.0.1', port="8000",debug=False)

How to delete an dictionay after processing it in python

I am merging 4 files which has billions of records this script is just an example of what i want
In this script im trying to adding records into four dictionaries and atlast im merging those 4 dictionaries to one dictionar
I am trying to delete 2nd dictionary after it is getting processed(after merging is done into one final dictionary) but it is throwing some error
class project(object):
def one(self):
self.hash_1 = {}
self.hash_1["ramu"] = ["10","20"]
self.hash_1["se"] = ["1","2"]
def two(self):
self.hash_2 = {}
self.hash_2["ramu"] = ["0","2"]
self.hash_2["se"] = ["111","2w"]
def three(self):
self.hash_3 = {}
self.hash_3["ramu"] = ["44","22"]
self.hash_3["se"] = ["111121","25"]
def four(self):
self.hash_4 = {}
self.hash_4["ramu"] = ["4433","222"]
self.hash_4["se"] = ["16621","2532"]
def process(self):
self.final_hash = {}
for k in self.hash_1:
self.final_hash[k] = self.hash_1[k]
print k
if k in self.hash_2:
print self.hash_2[k]
else:
print "no"
del self.hash_2
if k in self.hash_3:
print self.hash_3[k]
else:
print "no"
del self.hash_3
if k in self.hash_4:
print self.hash_4[k]
else:
print "no"
del self.hash_4
print self.final_hash
e_obj = project()
e_obj.one()
e_obj.two()
e_obj.three()
e_obj.four()
e_obj.process()
Error:
e_obj.process()
File "hash_remove_test.py", line 31, in process
if k in self.hash_2:
AttributeError: 'project' object has no attribute 'hash_2'
I want to delete every dictionary after processing it ot else it is throwing memoryError (since data is big)
How to solve this problem?
Note: The whole idea is to delete every dictionary after merging it
Your for loop runs del self.hash_2 during its first iteration (after examining self.hash_2), so it will be gone when the second iteration starts.
If I can rephrase your question, what you want is a dictionary final_hash with "ramu" and "se" as keys and two corresponding value arrays that have all the values of ramu and se from hash_1, hash_2, hash_3 and hash_4, right? Here's how I'd do it:
def process(self):
final_hash = dict()
for key in self.hash_1:
if key not in final_hash:
final_hash[key]= []
final_hash[key].append(self.hash_1[key])
for key in self.hash_2:
final_hash[key].append(self.hash_2[key])
for key in self.hash_3:
final_hash[key].append(self.hash_3[key])
for key in self.hash_4:
final_hash[key].append(self.hash_4[key])
del(self.hash_1)
del(self.hash_2)
del(self.hash_3)
del(self.hash_4)
print final_hash["ramu"], final_hash["se"]
[['10', '20'], ['0', '2'], ['44', '22'], ['4433', '222']]
[['1', '2'], ['111', '2w'], ['111121', '25'], ['16621', '2532']]
I have just hard coded the process() function. If you have a lot other dictionaries that have to be merged together, you might want to consider automating that part.

What's the most idiomatic way to implement a stack for `dictionary` type in `Python`?

I am trying to implement a stack machine in Python using list as my stack and dictionary as current machine state. But it doesn’t work as planned. After some debugging I found out that when I store machine state into stack, and then change it state, the stored state changes also.
Here is an example demonstrating my problem:
MyStack = []
myState = {}
myState['param'] = '1'
MyStack.append(myState)
myState['param'] = '2'
MyStack.append(myState)
myState['param'] = '3'
MyStack.append(myState)
print(MyStack.pop())
print(MyStack.pop())
print(MyStack.pop())
the result is:
{'param': '3'}
{'param': '3'}
{'param': '3'}
And not
{'param': '3'}
{'param': '2'}
{'param': '1'}
As I would think
Evidently, Python stores in list not copies of my dictionary, but references to it. So, all stacked items in reality are the same myState object. When I’ve got this, I walked the problem around by using dictionary.copy() method like so: MyStack.append(myState.copy()). But it seems a bit unnatural.
So, the question is: which is the most idiomatic way to implement a stack for dictionary type in Python?
Here, you are passing the same myState object inside MyStack.append, which gets updated every time rather than creating a new one. SO, inside the list you are always getting same identical element.
Let's see a data flow of your program.
MyStack = []
myState = {} # An empty dictionary 'myState' created
myState['param'] = '1' # 'mystate' -> {'param':'1'}
MyStack.append(myState) # 'MyStack' -> [mystate] -> [{'param':'1'}]
myState['param'] = '2' # 'mystate' -> {'param':'2'}
MyStack.append(myState) # 'MyStack' -> [mystate,mystate ]
# -> [{'param':'2'},{'param':'2'}]
myState['param'] = '3' # 'mystate' -> {'param':'3'}
MyStack.append(myState) # 'MyStack' -> [mystate,mystate, mystate]
# -> [{'param':'3'},{'param':'3'},{'param':'3'}]
I hope, it is clear to you now.
How to solve this:
Ensure you are creating a new dictionary every time rather than using the same one.
Before myState['param'] = '2' and myState['param'] = '3', just call,
myState = myState.copy()
Code:
MyStack = []
myState = {}
myState['param'] = '1'
MyStack.append(myState)
myState = myState.copy()
myState['param'] = '2'
MyStack.append(myState)
myState = myState.copy()
myState['param'] = '3'
MyStack.append(myState)
print(MyStack.pop())
print(MyStack.pop())
print(MyStack.pop())
Output:
{'param': '3'}
{'param': '2'}
{'param': '1'}

Categories

Resources