Python comparison operators - python-2.7

I have two values e.g a=972 and b=11188.
I want to get the details of all entries from a tab delimited text file which lies in between both numbers. The python comparison operators <= and >= are returning wrong results.
I have used the <= and >= operators in the if statement.
if l1[3]<="18188" >="900" and l1[2]=="1":
and it is returning nothing.
when I write
if l1[3]<="18188":
it returns "18166 and 11188 as output". I ideally this if function must return "11188 ,972 and 3632".
This is the tab delimited file.
SRR6298199.1 16 1 3632 0 50M32S * 0 0 AACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACCC !!""""!"!"!"!!"!!!""""""!!!""""!"" NM:i:1 AS:i:48 XS:i:47
SRR6298199.10 0 1 972 0 40M274S * 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATCAATTTGAA !"""'$""!"!"""" NM:i:0 AS:i:40 XS:i:40 XP:Z:3,+18166143,41S36M237S,0,0;
SRR6298199.10 0 1 18166 0 41S36M237S * 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATCAATTT !"""!#!#$#$"!"""" NM:i:0 AS:i:36 XS:i:34 XP:Z:2,+9723273,40M274S,0,0;
SRR6298199.11 16 1 11188 0 1841S9M * 0 0 GACCAGTATCGGGCCGGCATAAGCCTCGAATTTCACCAGCA !!!!!!""!#!"%%&)(%-//.//,".,.+.-..&! NM:i:18 AS:i:81 XS:i:81
Here is the complete code.. please figure out why this code is not returning true results.
# EXTRACTING THE DETAILS OF READS ALIGNED ON CHR_1
fr=open("Sample.txt","r")
z=fr.read()
bz=z.split("\n")
temp1=[]
for bases in bz:
temp1.append(bases.split("\t"))
cc1=[]
se=[] #READ NAMES ALIGNED ON CHR_1
chr2=[] #READ NAMES ALIGNED ON CHR_2
for l1 in temp1:
if l1[3]<="18188" >="900" and l1[2]=="1":
#print(l1[3])
#cc1.append("#"+str(l1[0])+"\t"+"length="+str(len(l1[9]))+"\n"+l1[9]+"\n"+"+"+l1[0]+"\t"+"length="+str(len(l1[9]))+"\n"+l1[10])
cc1.append("#"+str(l1[0])+" "+"/1"+"\n"+"+"+"\n"+l1[9])
print(cc1)
I expect the output of if l1[3]<="18188" >="900" and l1[2]=="1": to be
['SRR6298199.1', '16', '1', '3632', '0', '50M32S', '*', '0', '0', 'AACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACCC', '!!""""!"!"!"!!"!!!""""""!!!""""!""', 'NM:i:1', 'AS:i:48', 'XS:i:47']
['SRR6298199.10', '0', '1', '972', '0', '40M274S', '*', '0', '0', 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATCAATTTGAA', '!"""\'$""!"!""""', 'NM:i:0', 'AS:i:40', 'XS:i:40', 'XP:Z:3,+18166143,41S36M237S,0,0;']
['SRR6298199.11', '16', '1', '11188', '0', '1841S9M', '*', '0', '0', 'GACCAGTATCGGGCCGGCATAAGCCTCGAATTTCACCAGCA', '!!!!!!""!#!"%%&)(%-//.//,".,.+.-..&!', 'NM:i:18', 'AS:i:81', 'XS:i:81']
['SRR6298199.10', '0', '1', '18166', '0', '41S36M237S', '*', '0', '0', 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATCAATTT', '!"""!#!#$#$"!""""', 'NM:i:0', 'AS:i:36', 'XS:i:34', 'XP:Z:2,+9723273,40M274S,0,0;']
but aforementioned if statement is returning [], an empty list

Two problems:
1) you misuse / misorder the comparisonoperators
if l1[3]<= "18188" >="900" and l1[2]=="1": # always false becase "1..." is never >= "9.."
should most probably be
if "900"<= l1[3] <="18188" and l1[2]=="1":
2) you use lexicografical comparison to compare numbers - this will fail because in lexicographical comparisons "9" is bigger then "1111111"
You can fix both errors using correct comparison syntax and float-values for comparison:
if 900 <= float(l1[3]) <= 18188 and l1[2]=="1":

Related

why does the last character disappear?

The file contents are:
min:1,2,3,4,5,6
max:1,2,3,4,5,6
avg:1,2,3,4,5,6
Code:
def avg_calc():
total = 0
nums_inLine = line[4: -1]
num_list = []
num_list = nums_inLine.split(',')
length = len(num_list)
print(num_list)
with open('input.txt', 'r', encoding='utf-8-sig') as in_file:
content = in_file.readlines()
for line in content:
if 'min' in line:
min_calc()
elif 'max' in line:
max_calc()
elif 'avg' in line:
avg_calc()
My problem is that the '6' in the third line disappears or replaced by a whitespace. Why does it do that?
Output:
['1', '2', '3', '4', '5', '']
final goal is to cast each element in the list to an int then perform calculations to calculate the average of the numbers.

Group repeating list objects with itertools.groupby()

I have a list, where I want to group the repeating objects into a single object in the new list. Basically, convert this:
s = ['0.352125', '1', '1', '1', '1', '0', '0', '0', '0', '0', '0', '0', '0', '0.241041', '0.313429', '1', '1']
to this:
s_new = ['0.352125', '4*1','8*0', '0.241041', '0.313429','2*1']
I have tried itertools.groupby() function (python 2.7) as below:
from itertools import groupby
s_g = [list(g) for k, g in groupby(s)]
s_new = [', '.join('{}*{}'.format(sum(1 for _ in g), k) for k, g in groupby(s_g))]
As a result, I get:
s_new = ["1*['0.352125'], 1*['1', '1', '1', '1'], 1*['0', '0', '0', '0', '0', '0', '0', '0'], 1*['0.241041'], 1*['0.313429'], 1*['1', '1']"]
Apparently, this is not the list format I'm trying to get. Could someone please help me with this?
You unnecessarily applied groupby twice and there's also no reason to use str.join.
You can use the following list comprehension instead:
['%s*' % len(l) * (len(l) > 1) + k for k, g in groupby(s) for l in (list(g),)]

Writing with numbers

I need to make a function that receives a string of numbers and the ouput is the letters that correspond to those numbers, like if you are sending a message on a cell phone. For example to get the letter 'A' the input should be '2', to get the letter 'B', the input should be '22', etc. For example:
>>>number_to_word('222 '233' '3'):
"CAFE"
The program needs to "go around" the number if the limit of the number is reached. For example, the letter 'A', can be these following inputs: '2', '2222','2222222', etc. Just like if your sending a text message on cell phone when you get pass 'C' ( which is'222' ) the program goes again to 'A', making '2222' it's key. Also, in the input, if the string is '233' the program must separate the different numbers, so this ('233') will be equal this ('2' '33')
I made a dictionary like this:
dic={'2':'A', '22':'B', '222':'C', '3':'D', '33':'E', '333':'F',..... etc}
But I don't know how to make the program "go around" if the input is '2222', and how do I take that number and assign it to the letter 'A'.
Feel free to ask any questions if you don't understand what I'm asking I would be glad to explain it with more detail. Thank you.
This seems to give the desired result:
NUMBERS = {'2': 'A', '22': 'B', '222': 'C', '3': 'D', '33':'E', '333': 'F'}
def normalize_number(number):
for item in number.split():
if len(set(item)) == 1:
yield item
else:
last = item[0]
res = [last]
for entry in item[1:]:
if entry == last:
res.append(entry)
else:
yield ''.join(res)
res = [entry]
last = entry
yield ''.join(res)
def number_to_word(number):
res = []
for item in normalize_number(number):
try:
res.append(NUMBERS[item])
except KeyError:
if len(item) >= 4:
end = len(item) % 3
if end == 0:
end = 3
res.append(NUMBERS[item[:end]])
return ''.join(res)
Test it:
>>> number_to_word('222 2 333 33')
'CAFE'
>>> number_to_word('222 2 333 3333')
'CAFE'
>>> number_to_word('222 2 333 333333')
'CAFE'
>>> number_to_word('222 2333 3333')
'CAFE'
The function normalize_number() turns numbers that have different digits into multiple numbers with only the same digit:
>>> list(normalize_number('222 2 333 3333'))
['222', '2', '333', '3333']
>>> list(normalize_number('222 2333 3333'))
['222', '2', '333', '3333']
>>> list(normalize_number('222 2 333 53333'))
['222', '2', '333', '5', '3333']

Is this valid C++ to initialize a 2D dynamic array?

This is in my teachers code, and it works for me using the GNU compiler, and for my teacher who is on a Mac, but for other classmates using Visual Studio, it throws a lot of errors. I'm thinking that with dynamic memory, you can't initialize something like this, or rather the C++ standard doesn't say you have to be able to. Am I correct in that?
store = new char*[rows];
store[0] = new char[6]{'1', '1', '1', '1', '1', '1'};
store[1] = new char[6]{'1', 'e', '1', '0', '0', '1'};
store[2] = new char[6]{'1', '0', '0', '0', '1', '1'};
store[3] = new char[6]{'1', '0', '0', 'm', '1', '1'};
store[4] = new char[6]{'1', '1', '1', '1', '1', '1'};
It is a valid list initialization. However for example MS VC++ 2010 does not support it,
Not all compilers support all features of the C++ 2011.

Array of array of string

I am doing one task and I need to find shortest path on graph.
There are no problems at all with algorithm. The problem is how to output paths from source to all other vertexes. Edges has names too, not only weights. How should I initialize matrix of strings correctly? Is it possible at all?
I want this code work:
printf(" -(%s)-> %d", names[prev][next], mas[j]);
mas[j] is array with vertexes
names - array of arrays of string
I am trying to initialize matrix this way:
string names[N][N] = {
{'0', 'A', '0', 'B', 'E', '0', '0', 'P1', '0'},
{'A', '0', 'D', 'I', '0', '0', '0', '0', '0'},
{'0', 'D', '0', '0', '0', 'H', 'F', '0', '0'},
{'B', 'I', '0', '0', '0', 'H', '0', '0', '0'},
{'E', '0', '0', '0', '0', '0', '0', 'P2', '0'},
{'0', '0', 'H', 'H', '0', '0', '0', '0', 'P4'},
{'0', '0', 'F', '0', '0', '0', '0', '0', 'P3'},
{'0', '0', '0', '0', '0', '0', '0', '0', '0'},
{'0', '0', '0', '0', '0', '0', '0', '0', '0'},
};
My programm: http://ideone.com/ZMiVPE
You're using the wrong quotes for string literals. Single quotes ' are used for character literals, and in fact 'P1' is a multi-character literal (which I'm certain you don't even want to mess with). Instead, use double quotes " around your literals.
The reason they all need to be string literals is because there is no std::string constructor that takes only a char. There is, however, a constructor that takes a C-style string (as created by a string literal).
Note that printf will expect a C-style string, so you'll need to do names[prev][next].c_str().