Value is getting changed after assign it to dictionary in Python - python

I have created a inputjson variable and then replacing "'" to '\a"' and creating a dictionary and assigning to json key but the output of newjson variable and dictionary key value is different. In dictionary output / is replaced by //. Can anyone help me with the reason behind this issue.
inputjson = {"project_path": "Store_Execution_Analytics/DSCI/Tech","project_path_pqm": "Store_Execution_Analytics/DSCI/Tech/","project_path_powerbi": "Store_Execution_Analytics/DSCI/Tech","input_db_name": "rtm_storeexecution_pqm"}
print("The existing json value is: " + str(inputjson))
newjson = str(inputjson).replace(r"'", r'\a"')
print("The new json value is: " + str(newjson))
dict1={}
dict1['json'] = newjson
print(dict1)
inputjson = {'gen': 'UAT', 'gen2': 'eu', 'json': '{"project_path": "Store_Execution_Analytics/DSCI/Tech","project_path_pqm": "Store_Execution_Analytics/DSCI/Tech/"}'}
How can I acheive below output in python?
output = {'gen': 'UAT', 'gen2': 'eu', 'json': '{\a"project_path\a": \a"Store_Execution_Analytics/DSCI/Tech\a",\a"project_path_pqm\a": \a"Store_Execution_Analytics/DSCI/Tech/\a"}'}

In python, the \ character is used to escape characters that otherwise have a special meaning, such as newline \n, backslash itself \\, or the quote character \'\". See more at https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals.
Now in the first print (i.e. print("The new json value is: " + str(newjson))), you pass a string to the print function. The print function then displays the string in the console with the escaped characters resolved (a newline char will appear as a true line separator instead of the \n character, etc.).
In the second print (i.e. print(dict1)), the concerned string is a key in the dictionary dict1. Printing a dictionary does not resolve escape characters as it prints the representation of its keys and values. This is why you see the \\ escaped.

This happens because you're putting the string into a dictionary and then printing the entire dictionary. In order for python to represent the dictionary value correctly it has to escape the \a's. You'll see though if you print the value specifically associated with the json key in dict1 it prints as expected.
inputjson = {"project_path": "Store_Execution_Analytics/DSCI/Tech","project_path_pqm": "Store_Execution_Analytics/DSCI/Tech/","project_path_powerbi": "Store_Execution_Analytics/DSCI/Tech","input_db_name": "rtm_storeexecution_pqm"}
print("The existing json value is: " + str(inputjson))
newjson = str(inputjson).replace(r"'", r'\a"')
print("The new json value is: " + str(newjson))
dict1={}
dict1['json'] = newjson
print(dict1['json']) // this prints as expected
Here's an example of this working. https://www.mycompiler.io/view/GmTFEYm

You need to do the replacement for the inputjson["json"], not for the whole dictionary, if you are interested only in "json" field.
inputjson = {'gen': 'UAT', 'gen2': 'eu', 'json': '{"project_path": "Store_Execution_Analytics/DSCI/Tech","project_path_pqm": "Store_Execution_Analytics/DSCI/Tech/"}'}
output = inputjson.copy()
output["json"] = output["json"].replace(r'"', r'\a"')
print(output)
print(output['json'])
# Outputs
## {'gen': 'UAT', 'gen2': 'eu', 'json': '{\\a"project_path\\a": \\a"Store_Execution_Analytics/DSCI/Tech\\a",\\a"project_path_pqm\\a": \\a"Store_Execution_Analytics/DSCI/Tech/\\a"}'}
## {\a"project_path\a": \a"Store_Execution_Analytics/DSCI/Tech\a",\a"project_path_pqm\a": \a"Store_Execution_Analytics/DSCI/Tech/\a"}

Related

reading escape character as string from a file is not interpreted correctly in python

I've a application.properties file, key-value pair depending on the condition I'm taking whether to consider single tab or double tab.
application.properties:
key1=\t
key2=\t\t
main.py
with open('application.properties', 'rt')
read and convert to key value pair
return props
str1 = 'abc xyz'
str2 = 'def jkl'
splitter1 = props['key1']
splitter2 = props['key2']
print(str1.split(splitter1)[1])
print(str1.split(splitter2)[1])
Indexerror: list of index out of range
print(type(splitter2) , splitter2)
<class 'str'> \t\t
Python processes \t in string literals, not string values. You'll have to replace the digraph \t with a tab character yourself. Something like
props = {}
with open('application.properties') as f:
for line in f:
name, value = line.strip().split('=')
props[name] = value.replace(r'\t', '\t')
If there are other escape sequences that you expect to appear, you'll have to handle them yourself as well.

Removing Single Quotes from a String Stored in an Array

I wrote code to append a json response into a list for some API work I am doing, but it stores the single quotes around the alphanumerical value I desire. I would like to get rid of the single quotes. Here is what I have so far:
i = 0
deviceID = []
while i < deviceCount:
deviceID.append(devicesRanOn['resources'][i])
deviceID[i] = re.sub('[\W_]', '', deviceID[i])
i += 1
if i >= deviceCount:
break
if (deviceCount == 1):
print ('Device ID: ', deviceID)
elif (deviceCount > 1):
print ('Device IDs: ', deviceID)
the desired input should look like this:
input Device IDs:
['14*************************00b29', '58*************************c3df4']
Output:
['14*************************00b29', '58*************************c3df4']
Desired Output:
[14*************************00b29, 58*************************c3df4]
As you can see, I am trying to use RegEx to filter non Alphanumeric and replace those with nothing. It is not giving me an error nor is it preforming the actions I am looking for. Does anyone have a recommendation on how to fix this?
Thank you,
xOm3ga
You won't be able to use the default print. You'll need to use your own means of making a representation for the list. But this is easy with string formatting.
'[' + ', '.join(f'{id!s}' for id in ids) + ']'
The f'{id:!s} is an f-string which formats the variable id using it's __str__ method. If you're on a version pre-3.6 which doesn't use f-strings, you can also use
'%s' % id
'{!s}'.format(id)
PS:
You can simplify you're code significantly by using a list comprehension and custom formatting instead of regexes.
ids = [device for device in devicesRanOn['resources'][:deviceCount]]
if deviceCount == 1:
label = 'Device ID:'
elif deviceCount > 1:
label = 'Device IDs:'
print(label, '[' + ', '.join(f'{id!s}' for id in ids) + ']')

Parse the json output for specific value [duplicate]

I'll be receiving a JSON encoded string from Objective-C, and I am decoding a dummy string (for now) like the code below. My output comes out with character 'u' prefixing each item:
[{u'i': u'imap.gmail.com', u'p': u'aaaa'}, {u'i': u'333imap.com', u'p': u'bbbb'}...
How is JSON adding this Unicode character? What's the best way to remove it?
mail_accounts = []
da = {}
try:
s = '[{"i":"imap.gmail.com","p":"aaaa"},{"i":"imap.aol.com","p":"bbbb"},{"i":"333imap.com","p":"ccccc"},{"i":"444ap.gmail.com","p":"ddddd"},{"i":"555imap.gmail.com","p":"eee"}]'
jdata = json.loads(s)
for d in jdata:
for key, value in d.iteritems():
if key not in da:
da[key] = value
else:
da = {}
da[key] = value
mail_accounts.append(da)
except Exception, err:
sys.stderr.write('Exception Error: %s' % str(err))
print mail_accounts
The u- prefix just means that you have a Unicode string. When you really use the string, it won't appear in your data. Don't be thrown by the printed output.
For example, try this:
print mail_accounts[0]["i"]
You won't see a u.
Everything is cool, man. The 'u' is a good thing, it indicates that the string is of type Unicode in python 2.x.
http://docs.python.org/2/howto/unicode.html#the-unicode-type
The d3 print below is the one you are looking for (which is the combination of dumps and loads) :)
Having:
import json
d = """{"Aa": 1, "BB": "blabla", "cc": "False"}"""
d1 = json.loads(d) # Produces a dictionary out of the given string
d2 = json.dumps(d) # Produces a string out of a given dict or string
d3 = json.dumps(json.loads(d)) # 'dumps' gets the dict from 'loads' this time
print "d1: " + str(d1)
print "d2: " + d2
print "d3: " + d3
Prints:
d1: {u'Aa': 1, u'cc': u'False', u'BB': u'blabla'}
d2: "{\"Aa\": 1, \"BB\": \"blabla\", \"cc\": \"False\"}"
d3: {"Aa": 1, "cc": "False", "BB": "blabla"}
Those 'u' characters being appended to an object signifies that the object is encoded in Unicode.
If you want to remove those 'u' characters from your object, you can do this:
import json, ast
jdata = ast.literal_eval(json.dumps(jdata)) # Removing uni-code chars
Let's checkout from python shell
>>> import json, ast
>>> jdata = [{u'i': u'imap.gmail.com', u'p': u'aaaa'}, {u'i': u'333imap.com', u'p': u'bbbb'}]
>>> jdata = ast.literal_eval(json.dumps(jdata))
>>> jdata
[{'i': 'imap.gmail.com', 'p': 'aaaa'}, {'i': '333imap.com', 'p': 'bbbb'}]
Unicode is an appropriate type here. The JSONDecoder documentation describe the conversion table and state that JSON string objects are decoded into Unicode objects.
From 18.2.2. Encoders and Decoders:
JSON Python
==================================
object dict
array list
string unicode
number (int) int, long
number (real) float
true True
false False
null None
"encoding determines the encoding used to interpret any str objects decoded by this instance (UTF-8 by default)."
The u prefix means that those strings are unicode rather than 8-bit strings. The best way to not show the u prefix is to switch to Python 3, where strings are unicode by default. If that's not an option, the str constructor will convert from unicode to 8-bit, so simply loop recursively over the result and convert unicode to str. However, it is probably best just to leave the strings as unicode.
I kept running into this problem when trying to capture JSON data in the log with the Python logging library, for debugging and troubleshooting purposes. Getting the u character is a real nuisance when you want to copy the text and paste it into your code somewhere.
As everyone will tell you, this is because it is a Unicode representation, and it could come from the fact that you’ve used json.loads() to load in the data from a string in the first place.
If you want the JSON representation in the log, without the u prefix, the trick is to use json.dumps() before logging it out. For example:
import json
import logging
# Prepare the data
json_data = json.loads('{"key": "value"}')
# Log normally and get the Unicode indicator
logging.warning('data: {}'.format(json_data))
>>> WARNING:root:data: {u'key': u'value'}
# Dump to a string before logging and get clean output!
logging.warning('data: {}'.format(json.dumps(json_data)))
>>> WARNING:root:data: {'key': 'value'}
Try this:
mail_accounts[0].encode("ascii")
Just replace the u' with a single quote...
print (str.replace(mail_accounts,"u'","'"))

Struggling to make a decrypter in python

Hello i have an encrypted message i have opened the file in python created a list from the text document of all the individual characters, I then want to add a key to each letter in the list.
print (chr((ord(Z+key)))) # takes the ASCII value of the letter adds the key then changes back into a character
My issue is how do i made Z+1 Equal A instead of [
Use congruent addition!
key = 5
for i in range(26):
print (chr((i + key) % 26 + ord('A')))
Like the comment says. if result > Z. Then you count up more number to result so that is becomes a.
result = chr(ord(Z+key))
if result > ord(Z):
result = chr(ord(Z+102))
i am not sure of it is 102 or 103.
An easy way out is to view both the message and the keys as bytes.
Then you can just perform an exclusive-or (^) for both encryption and decryption.
If you need readable output, use base64 encoding on the key and ciphertext before writing them to disk. You can use my onepad program as an example of this approach.

Python for loop scope

I'm trying to format a dictionary variable to use as a report. I want to recurse through the dictionary and concatenate the items from the dictionary into a formatted string that will be printed/emailed out to users. I'm having issues getting with the string variable (text) losing some of the text concatenated to it.
What I want is:
first \n
\t status: first did not have any updates to apply \n
second \n
\t status: first did not have any updates to apply \n
My function is:
def formatReport(report, text = ""):
for x in report:
if isinstance(report[x], dict):
text += "{0} \n".format(x)
formatReport(report[x], text)
else:
text += "\t{0}: {1} \n".format(x, report[x])
return text
When I call:
report = {'first': {'status': 'first did not have any updates to apply'}, 'second': {'status': 'second did not have any updates to apply'}}
formatReport(report)
I get (note the order of the output is not important to me):
'second \nfirst \n'
After adding a ton of debugging:
def formatReport(report, text = ""):
for x in report:
print "before if: " + text
if isinstance(report[x], dict):
text += "{0} \n".format(x)
print "if: " + text
formatReport(report[x], text)
else:
text += "\t{0} : {1} \n".format(x, report[x])
print "else: " + text
return text
I have narrowed the issue to down to the fact that the text variable is losing the string appended after the else. ie on this line:
text += "\t{0} : {1} \n".format(x, report[x])
So the output of the debugging code after the else is run the first time in the first for loop looks like:
else: second
status : first did not have any updates to apply
When it loops back to the top of the for loop is looks like:
before if: second
From what I have read for loops and if/else statements do not have their own scope as Python does not have block level scoping. I'm at a lose here I have tried all kinds of different combinations or variable names, parameters, etc.... It's worth noting I want to run this code on dictionaries that are 3+ levels deep, hence the need for the recursive call in the if statement.

Categories