Can someone let me know how to pull out certain values from a Python output.
I would like the retrieve the value 'ocweeklyreports' from the the following output using either indexing or slicing:
'config': '{"hiveView":"ocweeklycur.ocweeklyreports"}
This should be relatively easy, however, I'm having problem defining the Slicing / Indexing configuation
The following will successfully give me 'ocweeklyreports'
myslice = config['hiveView'][12:30]
However, I need the indexing or slicing modified so that I will get any value after'ocweeklycur'
I'm not sure what output you're dealing with and how robust you're wanting it but if it's just a string you can do something similar to this (for a quick and dirty solution).
input = "Your input"
indexStart = input.index('.') + 1 # Get the index of the input at the . which is where you would like to start collecting it
finalResponse = input[indexStart:-2])
print(finalResponse) # Prints ocweeklyreports
Again, not the most elegant solution but hopefully it helps or at least offers a starting point. Another more robust solution would be to use regex but I'm not that skilled in regex at the moment.
You could almost all of it using regex.
See if this helps:
import re
def search_word(di):
st = di["config"]["hiveView"]
p = re.compile(r'^ocweeklycur.(?P<word>\w+)')
m = p.search(st)
return m.group('word')
if __name__=="__main__":
d = {'config': {"hiveView":"ocweeklycur.ocweeklyreports"}}
print(search_word(d))
The following worked best for me:
# Extract the value of the "hiveView" key
hive_view = config['hiveView']
# Split the string on the '.' character
parts = hive_view.split('.')
# The value you want is the second part of the split string
desired_value = parts[1]
print(desired_value) # Output: "ocweeklyreports"
Introduction to the problem
I have inputs in a .txt file and I want to 'extract' the values when a velocity is given.
Inputs have the form: velocity\t\val1\t\val2...\tvaln
[...]
16\t1\t0\n
1.0000\t9.3465\t8.9406\t35.9604\n
2.0000\t10.4654\t9.9456\t36.9107\n
3.0000\t11.1235\t10.9378\t37.1578\n
[...]
What have I done
I have written a piece of code to return values when a velocity is requested:
def values(input,velocity):
return re.findall("\n"+str(velocity)+".*",input)[-1][1:]
It works "backwards" because I want to ignore the first row from the inputs (16\t1\t0\n), this way if I call:
>>>values('inputs.txt',16)
>>>16.0000\t0.5646\t14.3658\t1.4782\n
But it has a big problem: if I call the function for 1, it returns the value for 19.0000
Since I thought all inputs would be in the same format I made a litte fix:
def values(input,velocity):
if velocity <= 5: #Because velocity goes to 50
velocity = str(velocity)+'.0'
return re.findall("\n"+velocity+".*",input)[-1][1:]
And it works pretty well, maybe is not the most beautiful (or efficient) way of do it but I'm a beginner.
The problem
But with this code I have a problem and it is that sometimes inputs have this form:
[...]
16\t1\t0\n
1\t9.3465\t8.9406\t35.9604\n
2\t10.4654\t9.9456\t36.9107\n
3\t11.1235\t10.9378\t37.1578\n
[...]
And, of course my solution doesn't work
So, is there any pattern that fit both kinds of inputs?
Thank you for your help.
P.S. I have a solution using the function split('\n') and indexes but I would like to solve it with re library:
def values(input,velocity):
return input.split('\n)[velocity+1] #+1 to avoid first row
You could use a positive look ahead to check that after your velocity there is either a period or a tab. That will stop you picking up further numbers without hardcoding there must be .0. This means that velocity 1 will be able to match 1 or 1.xxxxx
import re
from typing import List
def find_by_velocity(velocity: int, data: str) -> List[str]:
return re.findall(r"\n" + str(velocity) + r"(?=\.|\t).*", data)
data = """16\t1\t0\n1\t9.3465\t8.9406\t35.9604\n2\t10.4654\t9.9456\t36.9107\n3\t11.1235\t10.9378\t37.1578\n16\t1\t0\n1.0000\t9.3465\t8.9406\t35.9604\n2.0000\t10.4654\t9.9456\t36.9107\n3.0000\t11.1235\t10.9378\t37.1578\n"""
print(find_by_velocity(1, data))
OUTPUT
['\n1\t9.3465\t8.9406\t35.9604', '\n1.0000\t9.3465\t8.9406\t35.9604']
I have a g-code written in Fanuc g-code format including Macro-B (more info here), for example
#101 = 2.0 (first variable)
#102 = 0.1 (second variable)
#103 = [#101 + #102 * 3] (third variable using simple arithmetic)
G01 X#101 Y#103 F0.1
which should be converted to:
G01 X1.0 Y2.3 F0.1
more elaborate examples here and here.
things to be changed:
all instances of a variable slot should be replace with its value:
(#\d+)\s*=\s*(-?\d*\.\d+|\d+\.\d*)
arithmetic +, -, * and / inside the [...] need to be calculated:
(#\d+)\s*=\s*\[(#\d+|(-?\d*\.\d+|\d+\.\d*))(\s*[+\-*/]\s*(#\d+|(-?\d*\.\d+|\d+\.\d*|\d+)))*\]
comments (...) could be ignored or removed.
I would appreciate if you could help me know how i can do this in Python and if the regex I have above is correct. Thanks for your support in advance.
P.S.1. Unfortunately I can't find the syntax highlighting for fenced code blocks for g-code
P.S.2. when changing floats to strings one should consider the issue with Python floating point handeling. I made this function to solve that:
def f32str(inputFloat):
"""
This function converts a Python float to a string with 3 decimals
"""
return str(f"{inputFloat:.3f}")
OK I found a piece of code which does the job. Assuming gcode is a multiline string read from a Fanuc G-code:
import re
import os
def f32str(inputFloat):
return str(f"{inputFloat:.3f}")
gcode = re.sub(r"\(.*?\)", "", gcode)
flag = len(re.findall(r"#\d+", gcode))
while 0 < flag:
cases = re.findall(r"((#\d+)\s*=\s*([-+]?\s*(\d*\.\d+|\d+\.?\d*)))", gcode)
for case in cases:
gcode = gcode.replace(case[0], "")
gcode = gcode.replace(case[0], case[1])
cases = re.findall(r"(\[(\s*[+-]?\s*(\d+(\.\d*)?|\d*\.\d+)(\s*[-+*\/]\s*[+-]?\s*(\d+(\.\d*)?|\d*\.\d+)\s*)*)\])", gcode)
for case in cases:
gcode = gcode.replace(case[0], f32str(eval(case[1])))
flag = len(re.findall(r"#\d+", gcode))
gcode = os.linesep.join([s for s in gcode.splitlines() if s.strip()])
this is probably the worst way to do this and there should be more efficient implementations. I will leave the rest to the Python experts.
There might be a question like this but I can't find it.
I want to be to add the name of a variable/integer. e.g.
num = 5
chr(0x2075)
Now the 2nd line would return 5 in superscript but I want to put the word num into the Unicode instead so something like chr(0x207+num) would return 5 in superscript.
Any ideas? Thanks in advance
chr(0x2070 + num)
As given in the comment, if you want to get the character at U+207x, this is correct.
But this is not the proper way to find the superscript of a number, because U+2071 is ⁱ (superscript "i") while U+2072 and U+2073 are not yet assigned.
>>> chr(0x2070 + 1)
'ⁱ'
The real superscripts ¹ (U+00B9), ² (U+00B2), ³ (U+00B3) are out of place.
>>> chr(0xb9), chr(0xb2), chr(0xb3)
('¹', '²', '³')
Unfortunately, like most things Unicode, the only sane solution here is to hard code it:
def superscript_single_digit_number(x):
return u'⁰¹²³⁴⁵⁶⁷⁸⁹'[x]
Here's what I've got so far:
def encodeFive(zip):
zero = "||:::"
one = ":::||"
two = "::|:|"
three = "::||:"
four = ":|::|"
five = ":|:|:"
six = ":||::"
seven = "|:::|"
eight = "|::|:"
nine = "|:|::"
codeList = [zero,one,two,three,four,five,six,seven,eight,nine]
allCodes = zero+one+two+three+four+five+six+seven+eight+nine
code = ""
digits = str(zip)
for i in digits:
code = code + i
return code
With this I'll get the original zip code in a string, but none of the numbers are encoded into the barcode. I've figured out how to encode one number, but it wont work the same way with five numbers.
codeList = ["||:::", ":::||", "::|:|", "::||:", ":|::|",
":|:|:", ":||::", "|:::|", "|::|:", "|:|::" ]
barcode = "".join(codeList[int(digit)] for digit in str(zipcode))
Perhaps use a dictionary:
barcode = {'0':"||:::",
'1':":::||",
'2':"::|:|",
'3':"::||:",
'4':":|::|",
'5':":|:|:",
'6':":||::",
'7':"|:::|",
'8':"|::|:",
'9':"|:|::",
}
def encodeFive(zipcode):
return ''.join(barcode[n] for n in str(zipcode))
print(encodeFive(72353))
# |:::|::|:|::||::|:|:::||:
PS. It is better not to name a variable zip, since doing so overrides the builtin function zip. And similarly, it is better to avoid naming a variable code, since code is a module in the standard library.
You're just adding i (the character in digits) to the string where I think you want to be adding codeList[int(i)].
The code would probably be much simpler by just using a dict for lookups.
I find it easier to use split() to create lists of strings:
codes = "||::: :::|| ::|:| ::||: :|::| :|:|: :||:: |:::| |::|: |:|::".split()
def zipencode(numstr):
return ''.join(codes[int(x)] for x in str(numstr))
print zipencode("32345")
This is made in python.
number = ["||:::",
":::||",
"::|:|",
"::||:",
":|::|",
":|:|:",
":||::",
"|:::|",
"|::|:",
"|:|::"
]
def encode(num):
return ''.join(map(lambda x: number[int(x)], str(num)))
print encode(32345)
I don't know what language you are usingm so I made an example in C#:
int zip = 72353;
string[] codeList = {
"||:::", ":::||", "::|:|", "::||:", ":|::|",
":|:|:", ":||::", "|:::|", "|::|:", "|:|::"
};
string code = String.Empty;
while (zip > 0) {
code = codeList[zip % 10] + code;
zip /= 10;
}
return code;
Note: Instead of converting the zip code to a string, and the convert each character back to a number, I calculated the digits numerically.
Just for fun, here's a one-liner:
return String.Concat(zip.ToString().Select(c => "||::::::||::|:|::||::|::|:|:|::||::|:::||::|:|:|::".Substring(((c-'0') % 10) * 5, 5)).ToArray());
It appears you're trying to generate a "postnet" barcode. Note that the five-digit ZIP postnet barcodes were obsoleted by ZIP+4 postnet barcodes, which were obsoleted by ZIP+4+2 delivery point postnet barcodes, all of which are supposed to include a checksum digit and leading and ending framing bars. In any case, all of those forms are being obsoleted by the new "intelligent mail" 4-state barcodes, which require a lot of computational code to generate and no longer rely on straight digit-to-bars mappings. Search USPS.COM for more details.