-1

I have a script that appends to a list from a text file. I then use ''.join(mylist) to convert to type str so I can query a DynamoDB table for the said str. This seems to work until I query the table. I notice I am getting empty responses. After printing out each str, I notice they are being returned vertically. How can I format the string properly so my calls to DynamoDB are successful?

import boto3
from boto3.dynamodb.conditions import Key, Attr

dynamo = boto3.resource('dynamodb')
table = dynamo.Table('mytable')

s3.Bucket('instances').download_file('MissingInstances.txt')

with open('MissingInstances.txt', 'r') as f:
    for line in f:
        missing_instances = []
        missing_instances.append(line)
        unscanned = ''.join(missing_instances)

    for i in unscanned:
        print(i)
        response = table.query(KeyConditionExpression=Key('EC2').eq(i))
        items = response['Items']
        print(items)

Contents of MissingInstances.txt:

i-xxxxxx
i-yyyyyy
i-zzzzzz
etc etc

Output of print(i):

i
-
x
x
x
x
x

i
-
y
y
y
y
y

etc etc

Output of print(items):

[]
[]
[]
etc etc

Desired output:

i-xxxxxx
i-yyyyyy
etc etc
dmn0972
  • 363
  • 2
  • 8
  • 21
  • I don't see any `print` function calls where you use the `''.join(iterable)` idiom. – PMende Sep 20 '18 at 22:24
  • 1
    Possible duplicate of [How to print without newline or space?](https://stackoverflow.com/questions/493386/how-to-print-without-newline-or-space) – Thomas Ingalls Sep 20 '18 at 22:25
  • @PMende When i use the `print()` function like so: `unscanned = print(''.join(missing_instances))` I get the following error: `'NoneType' object is not iterable` – dmn0972 Sep 20 '18 at 22:26
  • You are looping through the output (`joined`) string and printing. – Nouman Sep 20 '18 at 22:39
  • 1
    I don't think this is a duplicate of that question @ThomasIngalls . It looks like the OP's problem is bigger than just needing to sort out the print function, but the title and content should be edited to accommodate this. – girlvsdata Sep 21 '18 at 03:51
  • 1
    @girlvsdata edited – dmn0972 Sep 21 '18 at 13:45

3 Answers3

1

Your problem isn't actually with the print function, but with how you are iterating your for loops. I've annotated your code below, added a tip to save you some time, and included some code to get you over this hurdle. Here is a resource for for loops, and here is another resource for using lists.


Here is your code, with annotations of what's happening:

#import libraries, prepare the data
import boto3
from boto3.dynamodb.conditions import Key, Attr
dynamo = boto3.resource('dynamodb')
table = dynamo.Table('mytable')
s3.Bucket('instances').download_file('MissingInstances.txt')

#Opens the text file that has the name of an instance and a newline character per line
with open('MissingInstances.txt', 'r') as f:
    #For each line in the text file
    for line in f:
        #(For each line) Create an empty list called missing_instances
        missing_instances = []
        #Append this line to the empty list
        missing_instances.append(line)
        #Put all the current values of the list into a space-delimited string
        #(There is only one value because you have been overwriting the list every loop)
        unscanned = ''.join(missing_instances)

At this point in the code, you have looped through and written over missing_instances every iteration of your loop, so you are left with only the last instance.

#This should print the whole list of missing_instances
>>>print(*missing_instances)
i-cccccc

#This should print the whole unscanned string
>>>print(unscanned)
i-cccccc

Next, you loop through unscanned:

    #For each letter in the string unscanned
    for i in unscanned:
        #Print the letter
        print(i)
        #Query using the letter (The rest of this won't work for obvious reasons)
        response = table.query(KeyConditionExpression=Key('EC2').eq(i))
        items = response['Items']
        print(items)

You don't need to join the list to convert to string

I have a script that appends to a list from a text file. I then use ''.join(mylist) to convert to type str so I can query a DynamoDB table for the said str

For example:

If you have this list:

missing_instances = ['i-xxxxxx','i-yyyyyy','i-zzzzzz']

You can see it's datatype is list:

>>>print(type(missing_instances))
<class 'list'>

But if you are looking at an element of that list (eg. the first element), the element's data type is str:

>>>print(type(missing_instances[0]))
<class 'str'>

This code loops through the text file and queries each line to the database:

#import libraries, prepare the data
import boto3
from boto3.dynamodb.conditions import Key, Attr
dynamo = boto3.resource('dynamodb')
table = dynamo.Table('mytable')
s3.Bucket('instances').download_file('MissingInstances.txt')

#Open the text file
with open('MissingInstances.txt', 'r') as f:
    #Create a new list
    missing_instances = []
    #Loop through lines in the text file
    for line in f:
        #Append each line to the missing_instances list, removing the newlines
        missing_instances.append(line.rstrip())

    #CHECKS
    #Print the whole list of missing_instances, each element on a new line
    print(*missing_instances, sep='\n')
    #Print the data type of missing_instances
    print(type(missing_instances))
    #Print the data type of the first element of missing_instances
    print(type(missing_instances[0]))

    #Loop through the list missing_instances
    #For each string element of missing_instances
    for i in missing_instances:
        #Print the element
        print(i)
        #Query the element
        response = table.query(KeyConditionExpression=Key('EC2').eq(i))
        #Save the response
        items = response['Items']
        #Print the response
        print(items)

#For good measure, close the text file        
f.close()
girlvsdata
  • 1,596
  • 11
  • 21
0

Try stripping of newline characters before appending them to the list.

For example:

missing_instances.append(line.rstrip())
Ricky Kim
  • 1,992
  • 1
  • 9
  • 18
0

Print automatically introduces a new line on each call. It does not work like Java's System.out#print(String). For example, when I run this, I get this:

for c in 'adf':
    print(c)

a
d
f

This is because in python (for some reason or another), strings are iterable.

I'm not sure what your code is in fact trying to do. I'm not familiar with this Boto3 library. But let's say the part i-xxxxx is decomposed to i and xxxxx, which I term id and other_stuff. Then,

for the_id in ids:
    print(f'{the_id}-{ids}')
ifly6
  • 5,003
  • 2
  • 24
  • 47
  • 1
    "in python (for some reason or another), strings are iterable." --- they are iterable because they provide `__getitem__()` and `__len__()` methods, which is enough to make an item iterable. – alkasm Sep 20 '18 at 22:50