-1

I have a text file data.txt, containing a table whose first few entries look like this:

                      PERIOD
CHANNELS    1      2      3      4       5 
   0       1.51   1.61   1.94   2.13   1.95 
   5       1.76   1.91   2.29   2.54   2.38 
   6       2.02   2.22   2.64   2.96   2.81 
   7       2.27   2.52   2.99   3.37   3.24 
   8       2.53   2.83   3.35   3.79   3.67 
   9       2.78   3.13   3.70   4.21   4.09 
  10       3.04   3.44   4.05   4.63   4.53...

The channel column contains the values of channels of an instrument. The other 5 columns contain the values of maximum energies a particular channel can detect in 5 different time periods.

I want to write a python program which takes the period, lower energy and higher energy values from the user and based on the period, finds out lower energy channel and higher energy channel corresponding to the lower energy value and higher energy value given by the user.

For example:

Period = input('Enter the period: ')
>> 1
lower_energy = float(input('Enter the lower energy value: '))
>> 2.02
higher_energy = float(input('Enter the higher energy value: '))
>> 2.60
The lower energy channel is 6
The higher energy channel is 9

I can write it using nested if conditions as follows:

If period = 1:
    if lower_energy < 1.51:
        lower_energy_channel = 0
    elif lower_energy < 1.76:
        lower_energy_channel = 5
    elif lower_energy < 2.02:
        lower_energy_channel = 6
    ... 

    If upper_energy < 1.51:
    upper_energy_channel = 0
    elif upper_energy < 1.76:
    upper_energy_channel = 5
    ... 

Similarly for all periods...

But my table is very long and that would be very cumbersome. I am looking for a cleaner solution to this.

The solution to this can be found here

2
  • Your question is not clear. Your code does not agree with your pseudocode, the overall purpose and variable meanings are not clear, I do not know the format of your "table" in the text file or in memory, etc. Please give more explanation and show a complete code snippet, according to How to create a Minimal, Complete, and Verifiable example. Commented Jul 17, 2018 at 11:55
  • I have edited my question and made it elaborate. I hope that it help in understanding it. Commented Jul 17, 2018 at 19:14

2 Answers 2

1

@Neal, you have a look at the below code. I've just tried to solve your problem in my way and written one method for code reusability.

I have used the concept of panda's DataFrame for storing tabular data and accessing data efficiently.

I have stored your given data in a file named data.txt.

data.txt

                     PERIOD
CHANNELS    1      2      3      4       5 
   0       1.51   1.61   1.94   2.13   1.95 
   5       1.76   1.91   2.29   2.54   2.38 
   6       2.02   2.22   2.64   2.96   2.81 
   7       2.27   2.52   2.99   3.37   3.24 
   8       2.53   2.83   3.35   3.79   3.67 
   9       2.78   3.13   3.70   4.21   4.09 
  10       3.04   3.44   4.05   4.63   4.53

Python code

import numpy as np
import pandas as pd 
def get_energy_details(file_name, period, low_energy, higher_energy, row_names=None, column_names=None):
    # READ FILE AND STORE THE DATA IN 2D LIST
    data_list = [] # FUTURE'S 2D LIST

    with open(file_name) as f:
        lines = f.readlines()[2:]
        for line in lines:
            arr = [float(num) for num in line.split()[1:]]
            data_list.append(arr)

    # PRINT 2D LIST
    print (data_list, '\n')

    # CREATING DataFrame FROM 2D LIST
    df = pd.DataFrame(data_list, columns=column_names, index=row_names)

    # PRINT DataFrame
    print (df, '\n')

    # SELECT THE SPECIFIC PERIOD (It is a Series object)
    print (df[period])

    # SORT THE SERIES AND STORE IT IN sorted_list
    sorted_list = df[period].sort_values() # A Series object

    # PRINT THE SORTED Series object
    print (sorted_list)

    # ************* MAIN LOGIC GOES HERE ****************
    # ************* LOWER ENERGY ************************
    found = False
    low_energy_level = None
    higher_energy_level = None

    for i, item in enumerate(sorted_list):
        print(i, item)
        if low_energy_level is not None and higher_energy_level is not None:
            break

        if item <= low_energy:
            low_energy_level = sorted_list.index[i]

        if item >= higher_energy:
            higher_energy_level = sorted_list.index[i]

    # OUTPUT
    return (low_energy_level, higher_energy_level) 


# start
if __name__ == '__main__':
    # INPUT 1
    period1 = int(input('Enter the period: '))
    lower_energy1 = float(input('Enter the lower energy value: '))
    higher_energy1 = float(input('Enter the higher energy value: '))
    row_names = [0, 5, 6, 7, 8, 9, 10]
    column_names = [1, 2, 3, 4, 5] 
    energies1 = get_energy_details('data.txt', period1, lower_energy1, higher_energy1, row_names, column_names)

    low_energy_level, higher_energy_level = energies1[0], energies1[1]
    print('\nLower energy: ', low_energy_level, 'Higher energy: ', higher_energy_level, '\n\n');

    # INPUT 2
    period2 = int(input('Enter the period: '))
    lower_energy2 = float(input('Enter the lower energy value: '))
    higher_energy2 = float(input('Enter the higher energy value: '))

    energies2 = get_energy_details('data.txt', period2, lower_energy2, higher_energy2)
    low_energy_level, higher_energy_level = energies2[0], energies2[1]
    print('\nLower energy: ', low_energy_level, 'Higher energy: ', higher_energy_level, '\n\n');

INPUT 1

Enter the period: 1
Enter the lower energy value: 2.02
Enter the higher energy value: 2.60
[[1.51, 1.61, 1.94, 2.13, 1.95], [1.76, 1.91, 2.29, 2.54, 2.38], [2.02, 2.22, 2.64, 2.96, 2.81], [2.27, 2.52, 2.99, 3.37, 3.24], [2.53, 2.83, 3.35, 3.79, 3.67], [2.78, 3.13, 3.7, 4.21, 4.09], [3.04, 3.44, 4.05, 4.63, 4.53]]

       1     2     3     4     5
0   1.51  1.61  1.94  2.13  1.95
5   1.76  1.91  2.29  2.54  2.38
6   2.02  2.22  2.64  2.96  2.81
7   2.27  2.52  2.99  3.37  3.24
8   2.53  2.83  3.35  3.79  3.67
9   2.78  3.13  3.70  4.21  4.09
10  3.04  3.44  4.05  4.63  4.53

0     1.51
5     1.76
6     2.02
7     2.27
8     2.53
9     2.78
10    3.04
Name: 1, dtype: float64
0     1.51
5     1.76
6     2.02
7     2.27
8     2.53
9     2.78
10    3.04
Name: 1, dtype: float64
0 1.51
1 1.76
2 2.02
3 2.27
4 2.53
5 2.78
6 3.04

Lower energy:  6 Higher energy:  9

INPUT 2

Enter the period: 2
Enter the lower energy value: 2.96
Enter the higher energy value: 3.01
[[1.51, 1.61, 1.94, 2.13, 1.95], [1.76, 1.91, 2.29, 2.54, 2.38], [2.02, 2.22, 2.64, 2.96, 2.81], [2.27, 2.52, 2.99, 3.37, 3.24], [2.53, 2.83, 3.35, 3.79, 3.67], [2.78, 3.13, 3.7, 4.21, 4.09], [3.04, 3.44, 4.05, 4.63, 4.53]]

      0     1     2     3     4
0  1.51  1.61  1.94  2.13  1.95
1  1.76  1.91  2.29  2.54  2.38
2  2.02  2.22  2.64  2.96  2.81
3  2.27  2.52  2.99  3.37  3.24
4  2.53  2.83  3.35  3.79  3.67
5  2.78  3.13  3.70  4.21  4.09
6  3.04  3.44  4.05  4.63  4.53

0    1.94
1    2.29
2    2.64
3    2.99
4    3.35
5    3.70
6    4.05
Name: 2, dtype: float64
0    1.94
1    2.29
2    2.64
3    2.99
4    3.35
5    3.70
6    4.05
Name: 2, dtype: float64
0 1.94
1 2.29
2 2.64
3 2.99
4 3.35
5 3.7

Lower energy:  2 Higher energy:  4
Sign up to request clarification or add additional context in comments.

5 Comments

I tried your code as it is and i get an error which looks something like this: File "energychannelconversion.py", line 17, in get_energy_details df = pd.DataFrame(data_list, columns=column_names, index=row_names) ValueError: Shape of passed values is (5, 8), indices imply (5, 7)
Please have a look at groups.google.com/forum/#!topic/airbnb_superset/mIstS7R_JUg. Update your packages like pandas etc. then try.
I resolved the error, thank you very much. However, i am getting erroneous values of Channels as output. For example: For the inputs - Period = 1, Lower energy = 1.00 and Higher energy = 2.00 the expected output is Lower energy channel = 0 and Higher energy channel = 6. But I am getting both Lower and Higher energy channel values as 6.
Okay, great. You are getting this for which i/p?
I don't understand your question. What do you mean by i/p? If you mean Inputs, then please refer to my previous comment.
0

Well, you have a table right there! Make it into a variable:

 table = [[1.51,   1.61,   1.94,   2.13,   1.95],
          [1.76,   1.91,   2.29,   2.54,   2.38],
          [2.02,   2.22,   2.64,   2.96,   2.81],
          ...
          [3.04,   3.44,   4.05,   4.63,   4.53]]

This is essentially a two-dimensional python list. You could go further by making more lists to "label the axes", so to speak:

period_axis = [1, 2, 3, 4, 5]
channel_axis = [0, 5, 6, 7, 8, 9, 10]

And now you can iterate through this array with one repeated if statement, rather than several similar ones:

period_idx = period_axis.index(period)     # Find table column corresponding to input
period_column = [row[0] for row in table]  # Use list comprehension to get a list
                                           #   comprised of JUST the column we want
lower_energy_idx = 0                       # Initialize lower_energy_channel index
for i in range(len(period_column)):        # Iterate through period_column by index
    if lower_energy < period_column[i]:    # This is your if statement from above
        lower_energy_idx = i

lower_energy_channel = channel_axis[i]     # use the channel axis to translate index
                                           # back into a useful number
...

Python is 0-indexed, so period_axis and channel_axis were necessary in order to convert from python's table indexing to your table's indexing. And I'm not sure I entirely understand your example, as this doesn't look at multiple columns at once. But the general idea here should be more or less clear: you can make a table and iterate over it however you need to, instead of using a bunch of if statements. Might not remove the if statements entirely, but at least it decreases the amount of them you'd have to use.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.