convert number to string - python

if I have a string s='ABCDEFJHI', and I slice it like this ['ABC','DEF','JHI'].
I have function encode(some calculation) which convert the sliced string into numbers.
for example 'encode('ABC' ) gives 50 , encode('DEF') gives 33, encode('JHI') gives 10
['ABC','DEF','JHI'] gives [50,33,10].
I want to do the reverse case, decode(50) gives 'ABC'
I have idea that when I encode sub-string , I create a library then I append sub-string with its number like: ('ABC':50)(do the same for all the sub-strings), later in decode I will just extract the sub-string according to the number.
How can I do this in python?

If it's reversible, I suggest to store it in reverse format (50: 'ABC'). And also, imagine a situation where the given code has not encoded before.
encode_history = {}
def encode(str):
"""some calculations which lead to the code"""
... your calculations ...
encode_history[code] = str
return code
def decode(code):
"""function to convert a code to string"""
if code in encode_history:
return encode_history[code]
else:
return None

In your encode function:
def encode(the_string):
#do whatever encoding you're doing
return (the_number,the_string)
and wherever you're using it, do:
d = dict()
for value in ["ABC","DEF","JHI"]:
encoded,decoded = encode(value)
d[encoded] = decoded
Define a function also like:
def decode(lookup_table,value):
return lookup_table[value]
and use it like:
encoded_values = list()
for value in ["ABC","DEF","JHI"]:
encoded,decoded = encode(value)
d[encoded] = decoded
encoded_values.append(encoded)
for value in encoded_values:
print("{} | {}".format(value,decode(d,value)))
[OUT]
50 | ABC
33 | DEF
10 | JHI
That said -- why are you doing this, how are you doing this, and why aren't you using some sort of real encryption for it? If it's not two-way encryption, you should almost certainly NOT be storing the data anywhere, and if it IS two-way encryption, why not just decrypt it using the opposite algorithm you used to encrypt? Just keep that in mind.....

Related

Python: Using bool() to select which vars are TRUE, then use those values to call function

First question ever! I've built a GUI which asks user to input 2 of possible 5 values. Each pair of values (10 possible pairs) get used to run 10 different solution functions named Case_n to which all five values (both zero and non-zero) are passed.
The problem I'm having is getting the bool() results stripped down to 2 digit without brackets, etc and then placed into a variable used to create the name of the function to call.
I've run the logic, with TRUE values added to a list, then converted the list to a string so I could strip it down to just the numerals, saved the 2 digit string and added it to the Case_n name. Now, when I try to use the name to call the function, I get an error that a string is not callable. Please help . . .
s = 5 #vars. For this example, I've pre-loaded 2 of them
a = 15
l = 0
r = 0
e_deg = 0
ve = 0
case = []
if bool(s):
case.append(1)
if bool(a):
case.append(2)
if bool(l):
case.append(3)
if bool(r):
case.append(4)
if bool(e_deg):
case.append(5)
nm = str(case) # placeholder to convert case to string
case_num = nm[1] + nm[4] # this returns 12 as a string
# create case_num var, using the string
Case = "Case_" + case_num
print("Case = ",Case) # Should be Case_12
def Case_12(s,a,l,r,e_deg,ve):
print("Case_12 running")
Case(s,a,l,r,e_deg,ve) ```
You could just use eval(Case) but I advise against it as you are processing user input and it could be a security risk.
An easy way would be to build the following dict :
my_dict = {"Case_1": Case_1, ..., "Case_12" : Case_12}
And then, instead of calling Case, you would do
my_dict[Case](s,a,l,r,e_deg,ve)
You could also create a function :
def choose_case(my_case_as_str):
my_case_dict = {"Case_1": Case_1, ..., "Case_12": Case_12}
return my_case_dict[my_case_as_str]
And then call
choose_case(Case)(s,a,l,r,e_deg,ve)
By the way, you probably don't want your function and variable names to start with an uppercase letter. You also probably want to use a safer way to get user input (for example use Template str)

Conditionally modify multiple variables

Not quite sure what the correct title should be.
I have a function with 2 inputs def color_matching(color_old, color_new). This function should check the strings in both arguments and assign either a new string if there is a hit.
def color_matching(color_old, color_new):
if ('<color: none' in color_old):
color_old = "NoHighlightColor"
elif ('<color: none' in color_new):
color_new = "NoHighlightColor"
And so forth. The problem is that each of the arguments can be matched to 1 of 14 different categories ("NoHighlightColor" being one of them). I'm sure there is a better way to do this than repeating the if statement 28 times for each mapping but I'm drawing a blank.
You can at first parse your input arguments, if for example it's something like that:
old_color='<color: none attr:ham>'
you can parse it to get only the value of the relevant attribute you need:
_old_color=old_color.split(':')[1].split()[0]
That way _old_color='none'
Then you can use a dictionary where {'none':'NoHighlightColor'}, lets call it colors_dict
old_color=colors_dict.get(_old_color, old_color)
That way if _old_color exists as a key in the dictionary old_color will get the value of that key, otherwise, old_color will remain unchanged
So your final code should look similar to this:
def color_matching(color_old, color_new):
""" Assuming you've predefined colros_dict """
# Parsing to get both colors
_old_color=old_color.split(':')[1].split()[0]
_new_color=new_color.split(':')[1].split()[0]
# Checking if the first one is a hit
_result_color = colors_dict.get(_old_color, None)
# If it was a hit (not None) then assign it to the first argument
if _result_color:
color_old = _result_color
else:
color_new = colors_dict.get(_color_new, color_new)
You can replace conditionals with a data structure:
def match(color):
matches = {'<color: none': 'NoHighlightColor', ... }
for substring, ret in matches.iteritems():
if substring in color:
return ret
But you seems to have a problem that requires a proper parser for the format you are trying to recognize.
You might build one from simple string operations like "<color:none jaja:a>".split(':')
You could maybe hack one with a massive regex.
Or use a powerful parser generated by a library like this one

Increasing efficiency of a string filter

I have a long text file containing a number of strings. Here is the part of the file:
tyh89= 13
kb2= 0
78%= yes
###bb1= 7634.0
iih54= 121
fgddd= no
#aa1= 0
#aa2= 1
#$ac3= 0
yt##hh= 0
#j= 12.1
##hf= no
So, basically all elements have a common structure of: header= value. My goal is to search for elements, whose headers contain specific string parts and read out those elements' values.
A the moment I do it with a rather straight approach: open/read the whole file as a string, differentiate it into list of elements and run if/elif conditions over all elements using a for loop. I provide my code below.
Is it the most efficient way to do it? Or is there a more efficient way to do it with not implementing the loop?
def main():
print(list(import_param()))
def import_param():
fl = open('filename','r')
cn = fl.read()
cn = cn.split('\n')
fl.close()
for st in cn:
if 'fgddd' in st:
el = st.split(' ')
yield float(el[1])
elif '#j' in st:
el = st.split(' ')
yield float(el[1])
if __name__ == '__main__': main()
yes, there is. You have to avoid testing if string contains a string, but rather focus on string equality.
Once you settle for equality, it means that you can create a set with the known keywords, split according to = and test if the set contains your value (using O(1) lookup):
key_set = {"fgddd","#j"}
for st in cn:
if '=' in st:
key,value = st.split("=",1)
if key in key_set:
el = value.strip()
yield float(el)
if you have different types, use a dictionary to convert to the proper type according to the key
key_set = {"fgddd":float ,"#j": float, "whatever":int , "something":str}
for st in cn:
if '=' in st:
key,value = st.split("=",1)
if key in key_set:
el = value.strip()
yield key_set[key](el) # apply type conversion
note that if you don't want any conversion, str will do the job as it returns itself when passed a string.
final note: if you have a say on the input format, suggest to use json instead of a custom format. Parsing becomes trivial using json module, and filtering can be achieved by the same way I've shown.

redis get the value from the result set

I have result returned as from ZrangebyScore function as [b'101']. I would like to extract only 101 value and discard other additional characters. It is in byte form. How to convert it in Integer format using Python.
If you are using Py3 try this:
mylist = [b'101']
val = int(mylist[0].decode())

How to get a value within a dictionary within a dictionary with just a string?

I'm trying to create a function that takes in a dictionary and a string and outputs a value within the Dictionary depending on the string.
For example, inputs would be:
D = {'assigned':{'id':4,'name':'myname'},'anotherkey':{'id':4,'name':'myname'}}
s = "['assigned']['id']"
Result:
4
This can also be achieved with the following, but the issue is that the function will only take a dictionary and a string
print D['assigned']['id']
>> 4
If you don't want to use eval(), you can of course parse out the fields of the string yourself, using regular expressions for instance:
import re
def lookup(d, s):
mo = re.match(r"\['([a-z]+)'\]\['([a-z]+)'\]", s)
if mo and len(mo.groups()) == 2:
return d[mo.group(1)][mo.group(2)]
return None
You can do simpler parsing too since the input is pretty fixed.
You can use eval, but you have to be sure that the string does contain things you want:
>>> eval("D"+s)
4
eval can do this
>>> D = {'assigned':{'id':4,'name':'myname'},'anotherkey':{'id':4,'name':'myname'}}
>>> s = "['assigned']['id']"
>>> eval("D" +s)
4

Categories