5
\$\begingroup\$

I apologize for the title, really didn't know what to call this program. In short, the program takes a file of values for the various atoms of amino acids, and then searches this file based on user input. I'm basically looking for any input on how to improve my script. I have a bad habit of using nested loops, splitting all the time, and poor naming. So any type of feedback on my code would be highly appreciated!

The file is a csv file that contains various information:

comp_id,atom_id,count,min,max,avg,std
ALA,H,86795,-0.914,69.229,8.193,0.641,488
ALA,HA,58922,-2.52,17.870,4.244,0.443,1135
ALA,MB,56709,-14.040,5.48,1.352,0.280,1024
ALA,C,55999,0.037,187.2,177.728,3.776,40
ALA,CA,76797,17.007,354.698,53.166,2.773,88
ALA,CB,72862,-40.993,318.868,19.052,3.066,200
ALA,N,82913,0.049,766,123.353,6.027,93
ARG,H,57814,0.011,178,8.241,1.052,36
ARG,HA,40349,1.212,12.57,4.289,0.469,471
....
VAL,CG2,43052,-5.648,320.420,21.346,2.531,92
VAL,N,75697,0.2,529,121.146,7.361,82

There are various amino acids (e.g. ALA, ARG, VAL), each has various different types of atoms (N,HA,CA,etc.). What I care about however is purely the Carbon atoms, and their attached Hydrogen (e.g. CA and HA,CB and MB, etc.). Specifically, the avg and std values (e.g. 8.193 and 0.641). The user can input their own carbon and hydrogen values, to see what amino acid it matches up with. Think of it as coordinates, you put in the latitude and longitude values, and it gives you the location. Since the 2 go together, both the Carbon and Hydrogen must match to get a printout (again, like latitude and longitude). So practice example:

#user inputs 52 and 4, they get a printout
ALA CA 53.166 2.773 ALA HA 4.244 0.443

Since 52 falls within 53.166+/-2.77 and 4 falls within 4.244+/-0.443, these coordinates designate ALA.
I've also added an additional 'High error' printout. Sometimes you get a match because the error is so high, it has a massive range. For these values, the range probably doesn't mean too much (still valuable info, but wanted the user to know if they got a match due to a high std). I chose 25% of the average as the definition for high error.

Finally, thought I'd also mention this since you might notice in my script there is a specific conditional on 'VALN'. This was because the way I determine if you move on to another amino acid, is by checking the current looped value, by the previous. However, when you reach the end of the file, the current will be the same as the end value (and subsequently, that amino acids lists will not get checked/printed). This is my "hackish" way of resolving this issue.

This is what I came up with:


def search_fun(carbon,hydrogen):
    """
    This will go through each amino acid, and check its carbon and hydrogen coordinates.
    If they are within the user inputed range, it will store these in the lists.
    Upon completing an amino acid, it will then go through all the matches, and print them out accordingly"""
    residue_list=[]
    carbon_list=[]
    hydrogen_list=[]
    with open('bmrb.csv') as file:
        for lines in file:
            if lines == '\n':
                continue
            split_lines=lines.split(',')
            residue=split_lines[0]
            if residue == 'comp_id':
                continue
            residue_list.append(residue)
            atom=split_lines[1]
            chemical_shift=float(split_lines[5])
            std=float(split_lines[6])
            lower_half=chemical_shift-std
            upper_half=chemical_shift+std
            if residue_list[0] != residue or (residue+atom) == 'VALN':
                if len(carbon_list) >= 1 and len(hydrogen_list) >= 1:
                    for values in carbon_list:
                        split_carbon=values.split()
                        for values2 in hydrogen_list:
                            split_hydrogen=values2.split()
                            if split_hydrogen[1][1] == split_carbon[1][1]:
                                if float(split_carbon[3]) > (0.25*float(split_carbon[2])) or float(split_hydrogen[3]) > (0.25*float(split_hydrogen[2])):
                                    print(f'{values} {values2} HIGH ERROR')
                                else:
                                    print(values,values2)
                    carbon_list.clear()
                    hydrogen_list.clear()
                else:
                    carbon_list.clear()
                    hydrogen_list.clear()
                    residue_list.clear()
                    residue_list.append(residue)
            if carbon>lower_half and carbon<upper_half:
                carbon_list.append(f'{residue} {atom} {chemical_shift} {std}')
            if hydrogen>lower_half and hydrogen<upper_half:
                hydrogen_list.append(f'{residue} {atom} {chemical_shift} {std}')

def main_loop():
    while True:
        question=input('input carbon and hydrogen values: ')
        split_question=question.split()
        search_fun(float(split_question[0]),float(split_question[1]))
        print('\n\n\n')

main_loop()

This is a test run of the output you should get using the above code and below csv file:

input carbon and hydrogen values: 42 3.2
ARG CD 43.201 2.938 ARG HD2 3.107 0.266
ARG CD 43.201 2.938 ARG HD3 3.091 0.285
ASP CB 40.895 2.563 ASP HB2 2.716 0.511
PHE CB 39.955 3.611 PHE HB2 2.992 0.381
PHE CB 39.955 3.611 PHE HB3 2.934 0.399
TYR CB 39.307 3.133 TYR HB2 2.898 0.466
TYR CB 39.307 3.133 TYR HB3 2.833 0.483

Here is the entire csv file:


comp_id,atom_id,count,min,max,avg,std
ALA,H,86795,-0.914,69.229,8.193,0.641,488
ALA,HA,58922,-2.52,17.870,4.244,0.443,1135
ALA,MB,56709,-14.040,5.48,1.352,0.280,1024
ALA,C,55999,0.037,187.2,177.728,3.776,40
ALA,CA,76797,17.007,354.698,53.166,2.773,88
ALA,CB,72862,-40.993,318.868,19.052,3.066,200
ALA,N,82913,0.049,766,123.353,6.027,93
ARG,H,57814,0.011,178,8.241,1.052,36
ARG,HA,40349,1.212,12.57,4.289,0.469,471
ARG,HB2,36605,-4.78,27.530,1.790,0.310,470
ARG,HB3,34641,-1.320,27.530,1.759,0.322,500
ARG,HD2,32127,-6.44,5.0,3.107,0.266,638
ARG,HD3,29287,-0.690,5.0,3.091,0.285,615
ARG,HE,10898,1.150,116.661,7.450,2.838,7
ARG,HG2,32714,-1.45,4.2,1.559,0.284,597
ARG,HG3,30376,-1.298,5.47,1.539,0.298,621
ARG,HH11,971,4.41,11.7,6.938,0.576,22
ARG,HH12,740,4.41,10.727,6.881,0.543,17
ARG,HH21,833,1.233,11.352,6.825,0.652,19
ARG,HH22,685,1.233,60.1410,6.905,2.136,1
ARG,C,35275,0.174,184.96,176.415,3.365,13
ARG,CA,49856,8.369,358.124,56.782,3.345,57
ARG,CB,46468,16.52,329.120,30.695,2.515,125
ARG,CD,27783,18.9350,342.642,43.201,2.938,46
ARG,CG,27535,12.17,328.290,27.260,3.041,42
ARG,CZ,743,43.199,184.497,160.136,7.440,8
ARG,N,53676,0.125,433.808,120.816,4.763,83
ARG,NE,6869,-23.150,149.1080,90.097,13.747,53
ARG,NH1,283,6.450,124.7890,78.516,13.368,6
ARG,NH2,248,66.2,128.470,78.360,13.933,7
ASN,H,47608,0.008,121.370,8.331,0.974,128
ASN,HA,33194,0.896,7.110,4.661,0.362,460
ASN,HB2,31112,-0.827,8.883,2.800,0.335,492
ASN,HB3,30047,-0.948,5.806,2.742,0.359,506
ASN,HD21,23425,0.783,111.320,7.337,0.850,48
ASN,HD22,23159,0.905,111.320,7.144,0.867,109
ASN,C,29727,0.114,185.3000,175.215,3.563,17
ASN,CA,41894,2.200,354.022,53.547,3.517,28
ASN,CB,39745,1.9620,342.798,38.727,3.598,45
ASN,CG,2689,0.000,185.503,176.229,8.760,11
ASN,N,44735,0.041,426.314,118.930,5.122,29
ASN,ND2,20306,21.038,1114.29,112.908,12.638,11
ASP,H,68763,-0.35,25.876,8.300,0.590,571
ASP,HA,46632,-3.75,8.66,4.585,0.327,680
ASP,HB2,43472,-5.2,37.4,2.716,0.511,75
ASP,HB3,41794,-1.46,37.2,2.667,0.518,100
ASP,HD2,18,1.160,12.30,5.991,3.334,0
ASP,C,43696,0.106,184.14,176.361,3.568,24
ASP,CA,60457,5.630,354.531,54.690,2.720,67
ASP,CB,57295,9.7,341.273,40.895,2.563,146
ASP,CG,963,2.637,188.215,177.196,18.089,13
ASP,N,66001,0.061,428.093,120.699,4.642,95
CYS,H,23821,3.723,12.660,8.380,0.695,148
CYS,HA,19401,-9.858,43.5,4.680,0.976,58
CYS,HB2,18672,-39.82,363.580,3.134,6.357,41
CYS,HB3,18201,-44.2,363.580,3.055,5.762,43
CYS,HG,254,-1.830,10.700,2.029,1.353,4
CYS,C,11404,1.000,187.591,174.775,3.469,10
CYS,CA,17149,30.6688,82.3,58.022,3.462,20
CYS,CB,16356,17.99,73.920,33.377,6.523,18
CYS,N,18895,-147,628,120.438,18.215,82
GLN,H,48881,0.000,66.542,8.216,0.653,231
GLN,HA,33387,0.403,7.43,4.264,0.432,551
GLN,HB2,30357,-1.514,10.461,2.043,0.276,415
GLN,HB3,28935,-1.4980,20.9,2.013,0.326,349
GLN,HE21,21428,-3.41,23.893,7.219,0.497,188
GLN,HE22,21310,1.025,113.695,7.036,0.879,29
GLN,HG2,28356,-1.76,33.5990,2.314,0.338,327
GLN,HG3,26350,-1.395,34.946,2.293,0.361,357
GLN,C,31356,0.069,1755.998,176.338,9.609,13
GLN,CA,43483,1.733,356.830,56.562,2.640,46
GLN,CB,40787,1.843,328.286,29.194,2.533,126
GLN,CD,2616,6.789,190.624,179.292,7.623,7
GLN,CG,25210,2.097,333.032,33.807,2.562,41
GLN,N,46869,0.000,418.059,119.962,4.176,126
GLN,NE2,19322,33.9,412.160,111.882,2.985,60
GLU,H,89195,0.008,122.9,8.330,0.743,322
GLU,HA,60909,0.433,8.02,4.242,0.413,1077
GLU,HB2,55127,-1.470,4.82,2.018,0.222,781
GLU,HB3,51907,-1.633,8.095,1.994,0.228,751
GLU,HE2,18,0.801,11.96,4.709,2.604,0
GLU,HG2,50906,-0.674,4.69,2.264,0.222,837
GLU,HG3,47453,-0.10,4.69,2.245,0.224,767
GLU,C,57652,0.074,184.71,176.828,4.280,40
GLU,CA,78638,1.056,360.826,57.327,3.270,75
GLU,CB,73549,9.08,330.834,30.019,3.150,117
GLU,CD,1013,0.000,198.609,181.090,14.839,8
GLU,CG,45672,6.16,337.230,36.143,2.948,64
GLU,N,85881,0.044,422.043,120.721,4.689,112
GLY,H,86072,-15.3,121.881,8.327,0.765,735
GLY,HA2,58056,-3.4,8.64,3.961,0.399,937
GLY,HA3,55297,-3.936,43.9930,3.888,0.439,773
GLY,C,54280,1.000,189.533,173.834,3.426,55
GLY,CA,76239,2.200,344.994,45.377,2.219,169
GLY,N,81099,0.2,791,109.680,7.053,192
HIS,H,24445,-0.3,13.34,8.256,0.733,261
HIS,HA,17566,0.676,11.38,4.617,0.565,230
HIS,HB2,16391,-2.168,45.897,3.159,1.118,129
HIS,HB3,15940,-6.2,38.5,3.100,1.087,138
HIS,HD1,1018,-15,86.5,9.987,8.570,23
HIS,HD2,11621,-25.85,67.8,7.148,3.262,90
HIS,HE1,9143,-26.6,134.811,7.831,2.535,63
HIS,HE2,388,-15,76.4,11.107,7.896,11
HIS,C,15093,1.000,184.204,175.133,4.716,15
HIS,CA,21851,11.40,355.084,56.521,3.407,62
HIS,CB,20513,13.496,329.046,30.324,3.186,56
HIS,CD2,7547,7.19,159.946,119.910,5.680,49
HIS,CE1,5913,8.198,166.282,137.244,5.712,55
HIS,CG,270,18.669,139.83,131.179,9.513,3
HIS,N,22875,0.2,427.146,119.658,5.239,41
HIS,ND1,816,31.026,261.013,193.109,32.573,2
HIS,NE2,754,17.0,257.572,180.840,20.342,20
ILE,H,59946,0.008,11.871,8.264,0.692,293
ILE,HA,41048,-9.0,173.538,4.167,1.009,7
ILE,HB,38633,-2.442,38.700,1.783,0.399,210
ILE,HG12,35114,-10.1,5.56,1.263,0.453,270
ILE,HG13,33779,-10.1,9.71,1.192,0.485,250
ILE,MD,38936,-4.15,13.891,0.671,0.332,621
ILE,MG,36922,-3.919,6.23,0.768,0.306,577
ILE,C,38288,0,187.551,175.800,4.524,29
ILE,CA,53038,20.877,362.184,61.623,3.359,62
ILE,CB,49504,-34.477,339.785,38.583,2.926,83
ILE,CD1,35029,2.7,314.600,13.505,3.480,110
ILE,CG1,31261,8.0,329.288,27.757,3.344,137
ILE,CG2,33140,0.79,317.615,17.608,3.243,97
ILE,N,57362,0.0000,531,121.425,6.042,89
LEU,H,99282,-0.3,13.220,8.219,0.651,501
LEU,HA,67703,0.000,119.411,4.303,0.644,70
LEU,HB2,62221,-1.522,8.02,1.607,0.360,803
LEU,HB3,59729,-1.79,8.39,1.523,0.376,865
LEU,HG,55123,-2.08,5.7,1.502,0.348,672
LEU,MD1,63101,-3.42,30.176,0.748,0.331,965
LEU,MD2,60780,-3.42,24.504,0.727,0.358,774
LEU,C,63540,0.071,189.78,176.991,3.682,29
LEU,CA,87816,1.056,158.320,55.653,2.236,189
LEU,CB,82155,7.439,93.180,42.248,2.020,527
LEU,CD1,54890,0.683,120.700,24.674,2.047,209
LEU,CD2,52489,0.280,116.300,24.119,2.125,161
LEU,CG,48288,0.000,75.280,26.805,1.494,354
LEU,N,94665,0.044,627,121.959,7.753,70
LYS,H,84117,0.002,64.423,8.175,0.668,498
LYS,HA,58613,-0.118,32.650,4.258,0.457,643
LYS,HB2,52752,-1.416,10.94,1.774,0.266,854
LYS,HB3,49716,-3.038,9.43,1.746,0.283,821
LYS,HD2,42396,-1.6800,119.620,1.607,0.643,29
LYS,HD3,38017,-2.02,29.047,1.595,0.272,557
LYS,HE2,41666,-0.493,42.02,2.911,0.289,457
LYS,HE3,36694,-0.046,7.344,2.903,0.223,782
LYS,HG2,47718,-1.654,6.7,1.363,0.272,978
LYS,HG3,44019,-1.83,5.575,1.348,0.283,923
LYS,C,51474,0.112,996.253,176.614,5.736,38
LYS,CA,71777,1.155,359.222,56.949,3.205,71
LYS,CB,67058,-26.686,332.988,32.791,2.923,94
LYS,CD,38624,0.834,329.284,28.997,2.640,75
LYS,CE,37258,-0.130,342.334,41.926,3.045,68
LYS,CG,40990,12.109,325.487,24.960,3.133,95
LYS,N,78570,0.041,427.245,121.038,4.691,124
LYS,NZ,303,1.950,177.2,51.816,33.019,2
LYS,QZ,1617,-10.9,10.506,7.339,1.046,44
MET,H,23446,-0.21,177,8.257,1.261,15
MET,HA,16662,-0.93,313.565,4.410,2.443,1
MET,HB2,14928,-27.312,33.750,2.024,0.583,84
MET,HB3,14085,-27.312,12.94,1.995,0.522,104
MET,HG2,13710,-33.86,32.7,2.376,1.463,44
MET,HG3,12981,-33.86,31.7,2.350,1.575,48
MET,ME,10583,-24.86,10.2000,1.773,1.563,79
MET,C,15432,2.200,183.25,176.200,3.324,5
MET,CA,21816,25.7283,85.327,56.149,2.289,59
MET,CB,20187,0.2,332.173,32.973,3.219,49
MET,CE,9592,0.000,317.645,17.254,4.252,53
MET,CG,11803,2.30,332.686,32.077,3.243,28
MET,N,22664,0.000,428.252,120.054,4.996,36
PHE,H,42717,-0.5,12.1759,8.337,0.731,262
PHE,HA,28990,1.33,59.70,4.618,0.727,23
PHE,HB2,27036,-0.463,7.979,2.992,0.381,371
PHE,HB3,26376,-0.212,12.72,2.934,0.399,389
PHE,HD1,22740,0.603,12.154,7.037,0.399,217
PHE,HD2,19220,0.603,12.154,7.038,0.412,194
PHE,HE1,19877,-2.838,14.080,7.062,0.453,167
PHE,HE2,16994,0,12.9,7.060,0.448,158
PHE,HZ,13928,-7.14,43.623,6.993,0.719,115
PHE,C,26768,0.088,184.929,175.449,3.069,9
PHE,CA,37271,4.917,363.618,58.107,3.822,36
PHE,CB,34997,2.161,341.700,39.955,3.611,44
PHE,CD1,13641,7.160,143.4500,131.172,5.998,70
PHE,CD2,9678,7.160,140.309,131.324,4.575,35
PHE,CE1,11887,0.000,149.609,130.316,5.835,61
PHE,CE2,8420,7.472,149.609,130.527,4.030,35
PHE,CG,421,7.229,152.844,137.247,11.620,4
PHE,CZ,8840,7.351,165.611,129.016,4.185,31
PHE,N,40480,0.067,422.843,120.393,5.461,51
PRO,H2,5,8.070,9.673,8.756,0.710,0
PRO,HA,33161,0.636,135.80,4.388,0.803,43
PRO,HB2,30818,-1.501,5.63,2.069,0.371,536
PRO,HB3,29932,-3.48,6.10,1.996,0.382,558
PRO,HD2,28519,-6.56,7.67,3.636,0.447,423
PRO,HD3,27539,-6.56,8.865,3.602,0.469,496
PRO,HG2,27730,-2.35,7.395,1.918,0.342,667
PRO,HG3,25811,-1.520,4.92,1.894,0.351,627
PRO,C,28640,0,183.517,176.630,4.386,30
PRO,CA,41044,0,363.087,63.330,3.613,80
PRO,CB,38296,0,333.586,31.887,3.162,71
PRO,CD,25032,1.155,350.648,50.343,3.214,61
PRO,CG,24932,2.436,327.402,27.277,3.727,44
PRO,N,2050,3.566,430,134.575,24.897,37
SER,H,72252,-15.3,116.95709,8.278,0.723,290
SER,HA,50558,1.277,58.739,4.477,0.475,421
SER,HB2,46319,0.61,9.182,3.867,0.278,725
SER,HB3,43053,0.61,41.7,3.843,0.343,503
SER,HG,924,0.13,11.36,5.422,1.193,23
SER,C,46531,0.000,197.1,174.589,3.254,32
SER,CA,65467,4.331,361.278,58.694,2.805,70
SER,CB,60788,-939.2800,365.087,63.723,4.984,170
SER,N,68552,0.000,416.964,116.292,4.253,189
THR,H,64336,0.02,21.7,8.233,0.640,534
THR,HA,44303,0.87,7.468,4.451,0.479,264
THR,HB,40659,0.087,71.587,4.168,0.655,78
THR,HG1,1629,-1.783,11.01,5.212,1.402,39
THR,MG,40565,-12.1,16.3,1.138,0.279,510
THR,C,40395,4.780,185.918,174.456,4.070,35
THR,CA,56552,0.971,92.659,62.210,2.759,104
THR,CB,52562,-939.2800,629.206,69.590,5.649,162
THR,CG2,34435,7.177,175.6,21.595,1.917,112
THR,N,61259,0.0,402,115.403,6.323,64
TRP,H,14089,3.421,17.315,8.269,0.781,92
TRP,HA,9794,2.043,11.414,4.678,0.534,77
TRP,HB2,9273,0.42,5.35,3.179,0.350,143
TRP,HB3,9017,-0.3776,7.972,3.116,0.372,137
TRP,HD1,8273,1.880,10.75,7.128,0.363,126
TRP,HE1,9199,-1.279,131.711,10.094,1.445,37
TRP,HE3,7185,1.85,12.233,7.299,0.525,128
TRP,HH2,7126,2.84,10.900,6.952,0.455,111
TRP,HZ2,7765,2.63,10.81,7.267,0.412,115
TRP,HZ3,6927,0.76,8.898,6.848,0.472,92
TRP,C,8460,2.500,184.30,175.973,6.049,12
TRP,CA,11894,2.966,362.099,57.713,4.800,12
TRP,CB,11102,1.6,328.795,30.089,4.784,23
TRP,CD1,5274,30.236,183.141,126.325,4.470,23
TRP,CD2,188,1.578,155.174,127.130,13.071,2
TRP,CE2,248,56.4176,177.710,137.535,9.569,6
TRP,CE3,4409,-10.872,174.807,120.173,5.545,29
TRP,CG,259,4.174,116.526,110.100,9.006,2
TRP,CH2,4655,-6.333,160.818,123.539,5.024,22
TRP,CZ2,5025,7.107,159.041,114.037,4.609,30
TRP,CZ3,4434,-8.702,161.540,121.151,4.660,22
TRP,N,12864,6.712,423.160,121.648,6.026,13
TRP,NE1,7540,0.53,435.960,129.269,6.295,31
TYR,H,36554,0.02,12.34,8.294,0.739,180
TYR,HA,25016,0.442,7.160,4.609,0.563,203
TYR,HB2,23316,-21.230,23.28,2.898,0.466,195
TYR,HB3,22790,-21.230,23.28,2.833,0.483,237
TYR,HD1,20167,0.190,10.5,6.920,0.373,237
TYR,HD2,17229,0.5522,10.499,6.916,0.377,211
TYR,HE1,19125,0.08,11.8,6.690,0.309,160
TYR,HE2,16443,0.43,11.7,6.690,0.320,147
TYR,HH,442,-0.788,31,9.103,2.096,5
TYR,C,22274,2.200,184.78,175.368,4.700,22
TYR,CA,31109,2.200,357.681,58.144,3.099,25
TYR,CB,28911,18.38,338.686,39.307,3.133,43
TYR,CD1,12301,19.589,141.572,132.361,5.290,65
TYR,CD2,8449,3.492,139.644,132.362,5.325,48
TYR,CE1,12085,40.435,182.764,117.730,4.101,109
TYR,CE2,8324,34.1221,154.10,117.772,3.349,68
TYR,CG,390,7.113,175.115,128.143,12.323,6
TYR,CZ,287,6.839,165.718,155.511,13.729,3
TYR,N,34074,0.2,818,120.749,11.899,35
VAL,H,78671,-0.41,120.980,8.271,0.790,168
VAL,HA,53950,-2.83,54.971,4.168,0.629,126
VAL,HB,50358,-27.480,31.75,1.979,0.450,389
VAL,MG1,50627,-27.2,24.20,0.819,0.333,562
VAL,MG2,49730,-27.2,56.56,0.801,0.431,245
VAL,C,50693,1,205.699,175.631,3.413,28
VAL,CA,69771,20.668,362.057,62.496,3.197,101
VAL,CB,64788,15.597025,331.747,32.716,2.289,140
VAL,CG1,44602,-7.4,321.185,21.547,2.434,90
VAL,CG2,43052,-5.648,320.420,21.346,2.531,92
VAL,N,75697,0.2,529,121.146,7.361,82
```
\$\endgroup\$
7
  • \$\begingroup\$ There are 7 column names, but 8 columns of data, is that intended? \$\endgroup\$
    – AMC
    Oct 10, 2020 at 0:40
  • \$\begingroup\$ @AMC I have no idea what that last column is. I didn't make the csv file, I downloaded that online from a site. But it doesn't effect the my script either way \$\endgroup\$
    – samman
    Oct 10, 2020 at 1:32
  • \$\begingroup\$ consider accepting an answer \$\endgroup\$
    – user228914
    Oct 13, 2020 at 18:27
  • \$\begingroup\$ @AryanParekh sorry completely forgot \$\endgroup\$
    – samman
    Oct 14, 2020 at 2:24
  • \$\begingroup\$ Use Pandas. It's made for this. \$\endgroup\$
    – Reinderien
    Oct 15, 2020 at 3:59

2 Answers 2

3
\$\begingroup\$

Simplify code!

  • with open('bmrb.csv') as file: followed by for lines in file: can be simplified into for lines in open("bmrb.csv").readlines():
  • with the change above you can completely remove if (lines == '\n') clause

Use Enum for clarity

split_lines[0], split_lines[1]. 0 and 1 are called magic numbers.

A magic number is a numeric literal (for example, 8080, 2048) that is used in the middle of a block of code without explanation. It is considered good practice to avoid magic numbers by assigning the numbers to named constants and using the named constants instead.

Instead what if you made an Enum called Data and named those constants?
Enums in Python

from enum import Enum
class Data(Enum):
    residue = 1
    atom = 2
    # the rest of the elements

Now when you want to refer to the 1st element, you can simply do split_lines[Data.atom.value] It is a little more typing, but it is also clearer as to what you mean from that line.

This also means you can remove the creation of copies. Not to create a new variable residue but just split_lines[Data.residue.value]

Format your code

if you write x = y + 65 compared to x+y=65 and x = float(y) compared to x=float(y), your code becomes much more readable

More simplification

question=input('input carbon and hydrogen values: ')
split_question=question.split()
search_fun(float(split_question[0]),float(split_question[1]))

becomes

carbon, hydrogen = map(float,input("Enter carbon and hydrogen values: ").split())
search_fun(carbon, hydrogen)

Split work into functions

you have this line

if float(split_carbon[3]) > (0.25*float(split_carbon[2])) or float(split_hydrogen[3]) > (0.25*float(split_hydrogen[2])):
    print(f'{values} {values2} HIGH ERROR')

Give a meaningful name to a new function where it would take in the various args and return True or False based on the formula. This way you can get rid of a lot of clunk in the search_fun() function.

if formula_1(Args...) or formula_2(Args...):
   print(f'{values} {values2} HIGH ERROR')

The same idea can apply to many other code segments, and make your code much more readable.

Using csv.DictReader

As suggested by @Graipher, it will be much better to use csv.DictReader as it will do a lot of the splitting work for you

from csv import DictReader
with open("csvfile.csv") as csvfile:
    reader = DictReader(csvfile, delimiter = ',')
    for line in reader:
        print(line['atom_id')

This will split the values into a dictionary, where the keys will be the words at the top of the file comp_id,atom_id,count,min,max,avg,std. This is much better as you won't need to split the lines manually, and there won't be any magic numbers as the keys to your dictionary will be pre-defined by you.
csv file handling in Python

\$\endgroup\$
14
  • 1
    \$\begingroup\$ Downvoter may i know your reason? \$\endgroup\$
    – user228914
    Oct 10, 2020 at 9:47
  • 2
    \$\begingroup\$ Thank you for the feedback! A couple of questions. 1. Does the for lines segment remove any spaces? I.E. How does changing that line negate the use of if line == '\n'. 2. If I want to split multiple values that aren't residue, doesn't that mean I will have multiple classes? Wouldn't it be cleaner to just split and use index values, rather than a bunch of classes defining various variable names? 3. So are you saying I should break my original function, into a bunch of smaller ones? \$\endgroup\$
    – samman
    Oct 11, 2020 at 1:15
  • 3
    \$\begingroup\$ @AryanParekh Recommending open("bmrb.csv").readlines(), which does not ensure closing of the file and reads the whole file in memory, recommending an unnecessary enum, when a csv.DictReader would be so much easier and making the user input parsing more fragile instead of less by e.g. recommending to write a function to deal with it. Sorry, did not have the time to comment when I first saw your answer. \$\endgroup\$
    – Graipher
    Oct 11, 2020 at 2:00
  • 1
    \$\begingroup\$ @AryanParekh The one thing the article doesn't talk about, and which is actually the greater reason for with is the case when an exception occurs. Granted, here there is not a lot of space for that to happen, but when using with, the closing happens even in case of exceptions. In any case, if you do recommend something which quite clearly goes against the normal recommendations, and even made the efforts to research if it is okay under some specific circumstances, then at least add a note about this in your answer. It currently reads like you should never need that verbose with stuff. \$\endgroup\$
    – Graipher
    Oct 11, 2020 at 6:34
  • 1
    \$\begingroup\$ Oh, and you missed to do either from csv import DictReader or reader = csv.DictReader(csvfile, delimiter=',') in your edit. \$\endgroup\$
    – Graipher
    Oct 11, 2020 at 6:36
1
\$\begingroup\$

Using csv.DictReader() in combination with itertools.groupby() would simplify processing the file. This presumes the rows in the file are grouped by comp_id.

from csv import DictReader
from itertools import groupby
from operator import itemgetter

with open('bmrb.csv') as file:
    # because we're using DictReader, each row is a dict keyed by column name
    reader = DictReader(file, restkey='extra')

    # group the rows by `comp_id`        
    grouper = groupby(reader, key=itemgetter('comp_id'))

    # rows is an iterable over the rows that have the same comp_id
    for comp_id,rows in grouper:

        # this is where you would process the group of rows, I just print some data
        print(comp_id)
        for row in rows:
            atom_id = row['atom_id']
            avg = float(row['avg'])
            std = float(row['std'])
            print(f'  {atom_id:4} {avg - std:6.2f} {avg + std:6.2f}')

It was too hard to figure out your code to process each row, so that is left as an exercise for someone else.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.