Trouble slicing based on function +1 - python

I am trying to search c_item_number_one = (r'12" Pipe SA-106 GR. B SCH 40 WALL smls'.upper()) for " to pull both it and all information in front of it. i.e. I want 12"
I thought I could just search for what position " is in...
def find_nps_via_comma_item_one():
nps = '"'
print(c_item_number_one.find(nps))
find_nps_via_comma_item_one()
Image showing above function results in 2
and then slice everything off after it
c_item_number_one = (r'12" Pipe SA-106 GR. B SCH 40 WALL smls'.upper())
def find_nps_via_comma_item_one():
nps = '"'
print(c_item_number_one.find(nps))
find_nps_via_comma_item_one()
item_one_nps = slice(3)
print(c_item_number_one[item_one_nps])
Issue: It is returning an error
print(c_item_number_one[item_one_nps])
TypeError: slice indices must be integers or None or have an __index__ method
How can I turn the results of my function into an integer? I've tried changing print(c_item_number_one.find(nps)) to return(c_item_number_one.find(nps)) but then it stopped giving a value entirely.
Lastly, the slice portion does not produce the full answer I am looking for 12". Even if I enter the value produced by the function 2
item_one_nps = slice(2)
print(c_item_number_one[item_one_nps])
It only gives me 12. I need to +1 the function results.

You could do
sep_char = "\""
c_item_number_one.split(sep_char)[0] + sep_char

The print statement prints a value to the console whereas a return returns a value where the function is call.
In your code you are not storing the value but just printing it to the console even when you used return instead of print you weren't making use of the returned value.
1 is being added to the slice since while slicing python excludes the stop index so to include the stop index you add 1
c_item_number_one = (r'12" Pipe SA-106 GR. B SCH 40 WALL smls'.upper())
def find_nps_via_comma_item_one():
nps = '"'
return(c_item_number_one.find(nps))
item_one_nps = slice(find_nps_via_comma_item_one()+1)
print(c_item_number_one[item_one_nps])
The following code is more verbose.
c_item_number_one = (r'12" Pipe SA-106 GR. B SCH 40 WALL smls'.upper())
def find_nps_via_comma_item_one():
nps = '"'
return(c_item_number_one.find(nps))
index = find_nps_via_comma_item_one()
item_one_nps = slice(index+1)
print(c_item_number_one[item_one_nps])

Related

Check if character within string; pass if True, do stuff if False

I am writing code to process a list of URL's, however some of the URL's have issues and I need to pass them in my for loop. I've tried this:
x_data = []
y_data = []
for item in drop['URL']:
if re.search("J", str(item)) == True:
pass
else:
print(item)
var = urllib.request.urlopen(item)
hdul = ft.open(var)
data = hdul[0].data
start = hdul[0].header['WMIN']
finish = hdul[0].header['WMAX']
start_log = np.log10(start)
finish_log = np.log10(finish)
redshift = hdul[0].header['Z']
length = len(data[0])
xaxis = np.linspace(start, finish, length)
#calculating emitted wavelength from observed and redshift
x_axis_nr = [xaxis[j]/(redshift+1) for j in range(len(xaxis))]
gauss_kernel = Gaussian1DKernel(5/3)
flux = np.convolve(data[0], gauss_kernel)
wavelength = np.convolve(x_axis_nr, gauss_kernel)
x_data.append(x_axis_nr)
y_data.append(data[0])
where drop is a previously defined pandas DataFrame. Previous questions on this topic suggested regex might be the way to go, and I have tried this to filter out any URL containing the letter J (which are only the bad ones).
I get this:
http://www.gama-survey.org/dr3/data/spectra/sdss/spec-0915-52443-0581.fit
http://www.gama-survey.org/dr3/data/spectra/sdss/spec-0915-52443-0582.fit
http://www.gama-survey.org/dr3/data/spectra/sdss/spec-0915-52443-0584.fit
http://www.gama-survey.org/dr3/data/spectra/sdss/spec-0915-52443-0587.fit
http://www.gama-survey.org/dr3/data/spectra/sdss/spec-0915-52443-0589.fit
http://www.gama-survey.org/dr3/data/spectra/sdss/spec-0915-52443-0592.fit
http://www.gama-survey.org/dr3/data/spectra/2qz/J113606.3+001155a.fit
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-8-2a3083a3a6d7> in <module>
14 finish_log = np.log10(finish)
15 redshift = hdul[0].header['Z']
---> 16 length = len(data[0])
17
18 xaxis = np.linspace(start, finish, length)
TypeError: object of type 'numpy.float32' has no len()
which is the same kind of error I was having before trying to remove J urls, so clearly my regex is not working. I would appreciate some advice on how to filter these, and am happy to provide more information as required.
There's no need to compare the result of re.search with True. From documentation you can see that search returns a match object when a match is found:
Scan through string looking for the first location where the regular expression pattern produces a match, and return a corresponding match object. Return None if no position in the string matches the pattern; note that this is different from finding a zero-length match at some point in the string.
So, when comparing a match object with True the return is False and your else condition is executed.
In [35]: re.search('J', 'http://www.gama-survey.org/dr3/data/spectra/2qz/J113606.3+001155a.fit') == True
Out[35]: False

iterating through a user defined list with arcpy

taxNo = arcpy.GetParameterAsText(0)
thisMap = arcpy.mapping.MapDocument("CURRENT")
myDF = arcpy.mapping.ListDataFrames(thisMap)[0]
myLayers = arcpy.mapping.ListLayers(myDF)
for lyr in myLayers:
if lyr.name == "Address Numbers":
arcpy.SelectLayerByAttribute_management(lyr,"NEW_SELECTION","EKEY = " + taxNo[0])
for tax in taxNo:
arcpy.SelectLayerByAttribute_management(lyr,"ADD_TO_SELECTION","EKEY = " + tax)
arcpy.AddWarning("Additional Selection " + tax)
I'm trying to build a script in ArcGIS that will select a series of user defined values, in this case I'm trying to select 1784102 and 1784110. When I use arcpy.AddWarning(taxNo) before the loop, I get the output "1784102;1784110" but it's iterating through it one number at a time i.e.
Additional Selection 1
Additional Selection 7
Additional Selection 8
Additional Selection 4
etc.
then pops up an error when it hits the semi-colon.
The parameters for taxNo are set up in ArcMap as a String, Multivalue, Valuelist.
I will just assume you are calling your script like this:
python script.py 1784102;1784110
Your variable taxNo = arcpy.GetParameterAsText(0) then is a single string "1784102;1784110". If you use "array indexes" on strings (for example taxNo[0], taxNo[1] etc.) you are getting single characters out of that string, i.e. "1", "7", "8" ...
Call .split(';') to your arcpy.GetParameterAsText(0) result to split the string "1784102;1784110" into an array of two strings: ["1784102", "1784110"]. If you need a numeric item, i.e. integers, try this too.
taxNo = arcpy.GetParameterAsText(0).split(';')

Python .join[] multiplys total string characters across multiple lines

I am working on a personal project to help my understanding of python 3.4.2 looping and concatenating strings from multiple sources.
My goal with this is to take 'string' use join and call __len__() inside to build a string it is multiplying my results. I would like the lengths to be 5 then 10 then 15. Right now it is coming out 5 then 25 then 105. If I keep going I get 425,1705,6825,etc...
I hope I'm missing something simple, but any help would be amazing. I'm also trying to do my joins efficiently (I know the prints aren't, those are for debugging purposes.)
I used a visualized python tool online to step through it and see if I could figure it out. I just am missing something.
http://www.pythontutor.com/visualize.html#mode=edit
Thank you in advance!
import random
def main():
#String values will be pulled from
string = 'valuehereisheldbythebeholderwhomrolledadtwentyandcriticalmissed'
#Initial string creation
strTest = ''
print('strTest Blank: ' + strTest)
#first round string generation
strTest = strTest.join([string[randomIndex(string.__len__())] for i in range(randomLength())])
print('strTest 1: ' + strTest)
print('strTest 1 length: ' + str(strTest.__len__()))
#second round string generation
strTest = strTest.join([string[randomIndex(string.__len__())] for i in range(randomLength())])
print('strTest 2: ' + strTest)
print('strTest 2 length: ' + str(strTest.__len__()))
#final round string generation
strTest = strTest.join([string[randomIndex(string.__len__())] for i in range(randomLength())])
print('strTest 3: ' + strTest)
print('strTest 3 length: ' + str(strTest.__len__()))
def randomIndex(index):
#create random value between position 0 and total string length to generate string
return random.randint(0,index)
def randomLength():
#return random length for string creation, static for testing
return 5
#return random.randint(10,100)
main()
# output desired is
# strTest 1 length: 5
# strTest 2 length: 10
# strTest 3 length: 15
The code runs without any issue, what's happening actually is, each time you call strTest.join(...), you are actually joining each random character and the next you get from string with the previous value of strTest.
Quoting from Python Doc:
str.join(iterable) Return a string which is the concatenation of the
strings in the iterable iterable. A TypeError will be raised if there
are any non-string values in iterable, including bytes objects. The
separator between elements is the string providing this method.
Example:
>>> s = 'ALPHA'
>>> '*'.join(s)
'A*L*P*H*A'
>>> s = 'TEST'
>>> ss = '-long-string-'
>>> ss.join(s)
'T-long-string-E-long-string-S-long-string-T'
So probably you want something like:
strTest = strTest + ''.join([string[randomIndex(string.__len__())] for i in range(randomLength())])

Pass integer from one def to another in Python

I'm trying to cross compare two outputs labeled "S" in compareDNA (calculating Hamming distance). Though, I cannot figure out how to call an integer from one def to another. I've tried returning the variable, but, I am unable to call it (in a different def) after returning it.
I'm attempting to see which output of "compareDNA(Udnalin, Mdnalin) and compareDNA(Udnalin, Hdnalin)" is higher, to determine which has a greater hamming distance.
How does one call an integer from one def to another?
import sys
def main():
var()
def var():
Mdna = open("mouseDNA.txt", "r")
Mdnalin = Mdna.readline()
print(Mdnalin)
Mdna.close
Hdna = open("humanDNA.txt", "r")
Hdnalin = Hdna.readline()
print(Hdnalin)
Hdna.close
Udna = open("unknownDNA.txt", "r")
Udnalin = Udna.readline()
print(Udnalin)
Udna.close
S = 0
S1 = 0
S2 = 0
print("Udnalin + Mdnalin")
compareDNA(Udnalin, Mdnalin)
S1 = S
print("Udnalin + Hdnalin")
compareDNA(Udnalin, Hdnalin)
def compareDNA(i, j):
diffs = 0
length = len(i)
for x in range(length):
if i[x] != j[x]:
diffs += 1
S = length - diffs / length
S = round(S, 2)
return S
# print("Mouse")
# print("Human")
# print("RATMA- *cough* undetermined")
main()
You probably want to assign the value returned by each call to compareDNA to a separate variable in your var function. Then you can do whatever you want with those values (what exactly you want to do is not clear from your question). Try something like this:
S1 = compareDNA(Udnalin, Mdnalin) # bind the return value from this call to S1
S2 = compareDNA(Udnalin, Hdnalin) # and this one to S2
# do something with S1 and S2 here!
If what you want to do is especially simple (e.g. comparing them to see which is larger), you could even use the return values directly in an expression, such as the condition in a if statement:
if compareDNA(Udnalin, Mdnalin) > S2 = compareDNA(Udnalin, Hdnalin):
print("Unknown DNA is closer to a Mouse")
else:
print("Unknown DNA is closer to a Human")
There's one further thing I'd like to point out, which is unrelated to the core of your question: You should use with statements to handle closing your files, rather than manually trying to close them. Your current code doesn't actually close the files correctly (you're missing the parentheses after .close in each case which are needed to make it a function call).
If you use a with statement instead, the files will be closed automatically at the end of the block (even if there is an exception):
with open("mouseDNA.txt", "r") as Mdna:
Mdnalin = Mdna.readline()
print(Mdnalin)
with open("humanDNA.txt", "r") as Hdna:
Hdnalin = Hdna.readline()
print(Hdnalin)
with open("unknownDNA.txt", "r") as Udna:
Udnalin = Udna.readline()
print(Udnalin)

Python: Function takes 1 argument for 2 given

I have looked on this website for something similar, and attempted to debug using previous answers, and failed.
I'm testing (I did not write this module) a module that changes the grade value of a course's grades from a B- to say a B, but never going across base grade levels (ie, B+ to an A-).
The original module is called transcript.py
I'm testing it in my own testtranscript.py
I'm testing that module by importing it: 'import transcript' and 'import cornelltest'
I have ensured that all files are in the same folder/directory.
There is the function raise_grade present in transcript.py (there are multiple definitions in this module, but raise_grade is the only one giving me any trouble).
ti is in the form ('class name', 'gradvalue')
There's already another definition converting floats to strings and back (ie 3.0--> B).
def raise_grade(ti):
""""Raise gradeval of transcript line ti by a non-noticeable amount.
"""
# value of the base letter grade, e.g., 4 (or 4.0) for a 4.3
bval = int(ti.gradeval)
print 'bval is:"' + str(bval) + '"'
# part after decimal point in raised grade, e.g., 3 (or 3.0) for a 4.3
newdec = min(int((ti.gradeval + .3)*10) % 10, 3)
print 'newdec is:"' + str(newdec) + '"'
# get result by add the two values together, after shifting newdec one
# decimal place
newval = bval + round(newdec/10.0, 1)
ti.gradeval = newval
print 'newval is:"' + str(newval) + '"'
I will probably get rid of the print later.
When I run testtranscript, which imports transcript:
def test_raise():
"""test raise_grade"""
testobj = transcript.Titem('CS1110','B-')
transcript.raise_grade('CS1110','B-')
cornelltest.assert_floats_equal(3.0,transcript.lettergrade_to_val("B-"))
I get this from the cmd shell:
TypeError: raise_grade takes exactly 1 argument (2 given)
Edit1: So now I see that I am giving it two parameters when raise_grade(ti) is just one, but perhaps it would shed more light if I just put out the rest of the code. I'm still stuck as to why I get a ['str' object has no gradeval error]
LETTER_LIST = ['B', 'A']
# List of valid modifiers to base letter grades.
MODIFIER_LIST = ['-','+']
def lettergrade_to_val(lg):
"""Returns: numerical value of letter grade lg.
The usual numerical scheme is assumed: A+ -> 4.3, A -> 4.0, A- -> 3.7, etc.
Precondition: lg is a 1 or 2-character string consisting of a "base" letter
in LETTER_LIST optionally followed by a modifier in MODIFIER_LIST."""
# if LETTER_LIST or MODIFIER_LIST change, the implementation of
# this function must change.
# get value of base letter. Trick: index in LETTER_LIST is shifted from value
bv = LETTER_LIST.index(lg[0]) + 3
# Trick with indexing in MODIFIER_LIST to get the modifier value
return bv + ((MODIFIER_LIST.index(lg[1]) - .5)*.3/.5 if (len(lg) == 2) else 0)
class Titem(object):
"""A Titem is an 'item' on a transcript, like "CS1110 A+"
Instance variables:
course [string]: course name. Always at least 1 character long.
gradeval [float]: the numerical equivalent of the letter grade.
Valid letter grades are 1 or 2 chars long, and consist
of a "base" letter in LETTER_LIST optionally followed
by a modifier in MODIFIER_LIST.
We store values instead of letter grades to facilitate
calculations of GPA later.
(In "real" life, one would write a function that,
when displaying a Titem, would display the letter
grade even though the underlying representation is
numerical, but we're keeping things simple for this
lab.)
"""
def __init__(self, n, lg):
"""Initializer: A new transcript line with course (name) n, gradeval
the numerical equivalent of letter grade lg.
Preconditions: n is a non-empty string.
lg is a string consisting of a "base" letter in LETTER_LIST
optionally followed by modifier in MODIFIER_LIST.
"""
# assert statements that cause an error when preconditions are violated
assert type(n) == str and type(lg) == str, 'argument type error'
assert (len(n) >= 1 and 0 < len(lg) <= 2 and lg[0] in LETTER_LIST and
(len(lg) == 1 or lg[1] in MODIFIER_LIST)), 'argument value error'
self.course = n
self.gradeval = lettergrade_to_val(lg)
Edit2: I understand the original problem... but it seems that the original writer screwed up the code, since raise_grade doesn't work properly for grade values at 3.7 ---> 4.0, since bval takes the original float and makes it an int, which doesn't work in this case.
You are calling the function incorrectly, you should be passing the testobj:
def test_raise():
"""test raise_grade"""
testobj = transcript.Titem('CS1110','B-')
transcript.raise_grade(testobj)
...
The raise_grade function is expecting a single argument ti which has a gradeval attribute, i.e. a Titem instance.

Categories

Resources