Search code examples
pythonpython-3.xlistbottlepetl

Want to create a key value pair list from csv file but unable to


I want to create a list of key-value pair with the output from /getService route.

I am able to filter the data that i wanted (Suburb and Services) from csv file vet_service_locations but want to have it as a key-value pair. Where keys are suburbs and services and values would be the relevant output.

I'm a beginner and tried different methods but nothing seems to work.

from bottle import html_quote, route, run, template, response, request
import petl as etl
from json import dumps
import csv


output = []

reading_file = etl.fromcsv('vet_service_locations.csv')
print(reading_file)


@route('/getServices')
def details():
    postcode = request.query.postcode
    print(postcode)
    for row in reading_file:
        if row[2] == postcode:
            output.append(row[1])
            output.append(row[4])
            
    print(output)
        
    

run(host='localhost', port=3000, debug=True)

Vet_service_location.csv data image is in this link

Output I'm getting

[('Adelaide', 'Small_Animal'), ('Adelaide', 'Oncology'), ('Adelaide', 'Surgery'), ('Adelaide', 'Annual_Checkup'), ('Adelaide', 'Wildlife')]

Output I want

 suburb, values 
[('Adelaide', 'Small_Animal'),  
('Adelaide', 'Oncology'),  
('Adelaide', 'Surgery'),  
('Adelaide', 'Annual_Checkup'),  
('Adelaide', 'Wildlife')]

So, kinda like the table, the same structure in which the vet_service_locations.csv is.


Solution

  • In addition to @Andrew's answer, try pprint to output the exact format as what you wanted.

    import pprint
    
    # ...
        # ...
        for row in reading_file:
            if row[2] == postcode:
                output.append((row[1], row[4]))
        
        print("suburb, values")    
        pprint.pprint(output)
    

    Output

    suburb, values
    [('Adelaide', 'Small_Animal'),
     ('Adelaide', 'Oncology'),
     ('Adelaide', 'Surgery'),
     ('Adelaide', 'Annual_Checkup'),
     ('Adelaide', 'Wildlife')]
    

    Or, if you want the output to be table-like, try using formatted string literals/ f-strings.

    # ...
        # ...
        sub_width = val_width = 0
        for row in reading_file:
            if row[2] == postcode:
                output.append((row[1], row[4]))
           
                # calculate the minimum width of each column
                sub_width = len(row[1]) if len(row[1]) > sub_width else sub_width
                val_width = len(row[4]) if len(row[4]) > val_width else val_width
    
    
        print(f"+{'='*(sub_width+2)}+{'='*(val_width+2)}+")
        print(f"| {'Suburb':{sub_width}} | {'Service':{val_width}} |")
        print(f"+{'='*(sub_width+2)}+{'='*(val_width+2)}+")
        for row in output:
            print(f"| {row[0]:{sub_width}} | {row[1]:{val_width}} |")
            print(f"+{'-'*(sub_width+2)}+{'-'*(val_width+2)}+")
    

    Output

    +==========+================+
    | Suburb   | Service        |
    +==========+================+
    | Adelaide | Small_Animal   |
    +----------+----------------+
    | Adelaide | Oncology       |
    +----------+----------------+
    | Adelaide | Surgery        |
    +----------+----------------+
    | Adelaide | Annual_Checkup |
    +----------+----------------+
    | Adelaide | Wildlife       |
    +----------+----------------+
    

    Alternatively, the output can also be fed to a template and returned as HTML table. You can pass any data you need to the template as template variables. You can name the variables whatever you want, as long as the template uses the same variable names.

    template(filepath, var1=data1, var2=data2, ...)
    

    Assume you have the following project structure

    project-name
     |-- views
     |    |-- index.tpl
     |  ...
     |-- main.py
    

    Revise your Python script

    # ...
        # ...
        for row in reading_file:
            if row[2] == postcode:
                output.append((row[1], row[4]))
    
        return template('views/index.tpl', title="Available Vet Service", header=["Suburb", "Values"], rows=output)
    

    Content of index.tpl

    <html lang="en">
      <head>
        <meta charset="utf-8">
        <link 
         rel="stylesheet" 
         href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" 
         integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" 
         crossorigin="anonymous"
        >
        <title>{{title}}</title>
      </head>
      <body>
        <div>
          <table class="table table-striped table-hover table-responsive-sm">
            <thead class="thead-dark">
              <tr>
                % for col_title in header:
                  <th scope="col">{{col_title}}</th>
                % end
              </tr>
            </thead>
            <tbody>
              % for cell in rows:
                <tr>
                  <td>{{cell[0]}}</td>
                  <td>{{cell[1]}}</td>
                </tr>
              % end
            </tbody>
          </table>
        </div>
      </body>
    </html>
    

    Here's the screenshot of the HTML output.

    Output as HTML Table