Reading ahead through a SQL query while looping in Python - python

The script executes a SQL query and returns a result like below:
subtract,'a','wrong'
subtract,'b','wrong'
add,a,'wrong'
add,b,'wrong'
add,c,'correct'
add,d,'wrong'
subtract,'a','wrong'
subtract,'b','wrong'
I loop through the results to read it line by line and store each element in a variable, but this is where I have no clue what to do next.
flag = 0
for rec in allRecords:
operation = rec[0]
value = rec[1]
answer = rec[2]
#if flag == 1:
#pass
#else:
if operation == 'add':
#start an inside loop to 'read ahead' and continue if operation == 'add' and stop when operation != 'add'
#find 'c' inside this loop and get the 'correct' element which is next to it and store in a new variable.
#break the loop to go back to main loop
#getVar = 'correct'
#print(getVar)
#flag = 1
else:
flag = 0
#after breaking out of the loop above, continue to the next records
print(rec)
Desired Output:
correct
add,a,'wrong'
add,b,'wrong'
add,c,'correct'
add,d,'wrong'
Why am I doing this?
I want to display the correct answer first and then list the rest of the options. Also practicing programming.
Why am I asking here?
I've exhausted all resource and I'm really stuck and in need of guidance. I googled all the errors I received from all of the trial and error I did and could not find an answer.
Tried my best to explain. I'm quite new to programming and just learning python. Appreciate your help.

One way is to traverse the records twice:
for operation, value, answer in allRecords:
if answer == 'correct':
print 'correct'
for operation, value, answer in allRecords:
if answer != 'correct':
print (operation, value, answer)

You could first make a subset of all additions, and then get the correct answer from that subset.
# Filter all additions from the results
additions = [[o, v, a] for o, v, a in results if o == 'add']
# Filter the addition with the correct answer
correct = [v for o, v, a in additions if a == 'correct']
# Output information
print "Correct : {}".format(correct)
for addition in additions:
print "{}, {}, {}".format(addition[0], addition[1], addition[2])
The code above outputs,
Correct : ['c']
add, a, wrong
add, b, wrong
add, c, correct
add, d, wrong

Related

How do I run a conditional statement "only once" and every time it changes?

I might be asking a simple question. I have a python program that runs every minute. But I would like a block of code to only run once the condition changes? My code looks like this:
# def shortIndicator():
a = int(indicate_5min.value5)
b = int(indicate_10min.value10)
c = int(indicate_15min.value15)
if a + b + c == 3:
print("Trade posible!")
else:
print("Trade NOT posible!")
# This lets the processor work more than it should.
"""run_once = 0 # This lets the processor work more than it should.
while 1:
if run_once == 0:
shortIndicator()
run_once = 1"""
I've run it without using a function. But then I get an output every minute. I've tried to run it as a function, when I enable the commented code it sort of runs, but also the processing usage is more. If there perhaps a smarter way of doing this?
It's really not clear what you mean, but if you only want to print a notification when the result changes, add another variable to rembember the previous result.
def shortIndicator():
return indicate_5min.value5 and indicate_10min.value10 and indicate_15min.value15
previous = None
while True:
indicator = shortIndicator()
if previous is None or indicator != previous:
if indicator:
print("Trade possible!")
else:
print("Trade NOT possible!")
previous = indicator
# take a break so as not to query too often
time.sleep(60)
Initializing provious to None creates a third state which is only true the first time the while loop executes; by definition, the result cannot be identical to the previous result because there isn't really a previous result the first time.
Perhaps also notice the boolean shorthand inside the function, which is simpler and more idiomatic than converting each value to an int and checking their sum.
I'm guessing the time.sleep is what you were looking for to reduce the load of running this code repeatedly, though that part of the question remains really unclear.
Finally, check the spelling of possible.
If I understand it correctly, you can save previous output to a file, then read it at the beginning of program and print output only if previous output was different.

Keep track of items in dynamic programming(similar to Knapsack problem)

Hello I'm trying to solve this dp problem: https://vjudge.net/problem/UVA-990
I'm able to solve the initial problem result using this code below:
I used recursion and a memo table arr to optimize the code.
s=list(map(int,input().split()))
t=s[0] #seconds allowed under water
w=s[1] #w
n=int(input()) #number of treasures
depth=[-1]
gold=[-1]
time=[-1]
for i in range(3):
q=list(map(int,input().split()))
depth.append(q[0])
gold.append(q[1])
time.append(q[0]*w*3)
arr = [[-1]*(t+1) for i in range(0,(n+1))]
def maxGold(n,T):
if n==0 or T==0:
return 0
if arr[n][T]!=-1:
return arr[n][T]
if time[n]>T:
answer=maxGold(n-1,T)
else:
answer=max(maxGold(n-1,T),gold[n]+maxGold(n-1,T-time[n]))
arr[n][T]=answer
return answer
result=maxGold(n,t)
print(result)
However I have no idea how to keep track of the chosen items.
I was thinking to store all indices of chosen treasures of the maxGold() output and print them later in a loop for instance.
One approach I had was to add a paramter to the maxGold() function and append to it the indices and return two result and the indices list from the function like the following:
def maxGold(n,T,l):
if n==0 or T==0:
return 0,l
if arr[n][T]!=-1:
return arr[n][T],l
if time[n]>T:
answer=maxGold(n-1,T,l)
else:
l2=l[:]
l2.append(n)
answer=max(maxGold(n-1,T,l)[0],gold[n]+maxGold(n-1,T-time[n],l2)[0])
arr[n][T]=answer
return answer,l
result=maxGold(n,t,[])
print(result[0])
list_of_indices=result[1]
length=len(list_of_indices)
#proceed outputs
However I ran into many tuple/integer type, subscriptable,iteratable errors. from this specific line even after trying to get a round the tuple output due to several outputs :
answer=max(maxGold(n-1,T,l)[0],gold[n]+maxGold(n-1,T-time[n],l2)[0])
And honestly I'm uncertain whether this approach is the right one.
Any hints?

Python, returning the integer from a tuple from an input

I am trying to make the input command streamlined, I don't know if I can explain this but here it goes.
out = input()
planOne = int(out)
planet = listplanets[planOne]
print(planet)
So listplanets is a tuple, if I input a number such as 0, it will return Mercury, how do I make it so I can input mercury and it will return Mercury. I want to keep the tuple format and I will also need the integer value of the tuple item in say var1. Would be greatly appreciated if someone can help me out. PS I know, I am a massive noob XD.
Edit: This is how my tuple is made
listplanets = ("Mercury"), (0.378), ("Venus"), (0.907), ("Mars"), (0.377), ("Io"), (0.1835), ("Europa"), (0.1335), ("Ganymede"), (0.1448), ("Callisto"), (0.1264)
Edit:
I am now using a dictionary, as suggested by you kind people.
listplanets = {
"Mercury": "Mercury",
"Mercury2": 0.378,
"Venus": "Venus",
"Venus2": 0.907,
"Mars": "Mars",
"Mars2": 0.377,
"Io": "Io",
"Io2": 0.1835,
"Europa": "Europa",
"Europa2": 0.1335,
"Ganymede": "Ganymede",
"Ganymede2": 0.1448,
"Callisto": "Callisto",
"Callisto2": 0.1264}
My reason for structuring it this way was for printing purposes, I am overcomplicating this!
I am not sure if it is against the rules to ask another question but it does relate to this post.
I am now trying to have it so when you type in mercury it will output On the planet of Mercury, this code below is not working for me, more help would be massively appreciated!
out = input().capitalize()
if out == listplanets:
print("On the planet of", listplanets[out])
else:
print("That was an incorrect format! Try again.")
planets()
For anyone that is curious, here is my code (Reason why it is not text is because this is my assignment, the anti plagerise tool would say I am copying my own code! XD):
---------------------------------------
The previous part was not shown clearly and that is why there is an image there
You can't use the slice operator directly listplanets[out] on a dictionary.
And you don't have to repeat the same thing over and over"mercury": "Mercury".
Use this format for your dictionary,
listplanets = {"Mercury": 0.378, "Venus": 0.907, "Mars": 0.377, "Io": 0.1835, "Europa": 0.1335, "Ganymede": 0.1448, "Call
and try this
out = input()
if out.isdigit(): #check if the input is digit
print(list(listplanets.keys())[int(out)]) #gets all key values to a list and so slicing can done
else:
print(listplanets[out.capitalize()]) #capitalize first letter
If you need to keep it tuple format you have to loop through your data like this:
# Data is given like this. First name and then value related to it.
listplanets = ("Mercury"), (0.378), ("Venus"), (0.907), ("Mars"), (0.377), ("Io"), (0.1835), ("Europa"), (0.1335), ("Ganymede"), (0.1448), ("Callisto"), (0.1264)
out = input("Planet: ")
for i in range(len(listplanets)):
if isinstance(listplanets[i], float):
# Skip values
continue
if out.lower() == listplanets[i].lower():
print ("{}: {}".format(listplanets[i], listplanets[i+1]))
But using dictionary is much better, as mentioned in comments.
How about this code?
# listplanets = ('Mercury', 'Earth')
In [19]: new_listplanets = [(index, {planet.lower(): planet}) for index, planet in enumerate(listplanets)]
# [(0, {'mercury': 'Mercury'}), (1, {'earth': 'Earth'})]
In [20]: new_listplanets[0][0]
Out[20]: 0
In [21]: new_listplanets[0][1]['mercury']
Out[21]: 'Mercury'

Nested Loop 'If'' Statement Won't Print Value of Tuple

Current assignment is building a basic text adventure. I'm having trouble with the following code. The current assignment uses only functions, and that is the way the rules of the assignment state it must be done.
def make_selections(response):
repeat = True
while repeat == True:
selection = raw_input('-> ')
for i, v in enumerate(response):
i +=1 # adds 1 to the index to make list indices correlate to a regular 1,2,3 style list
if selection == i:
print v[1]
else:
print "There's an error man, what are you doing?!?!?"
firstResponse = 'You chose option one.'
secondResponse = 'You chose option two.'
thirdResponse = 'You chose option three.'
responses = [(0, firstResponse), (1, secondResponse),( 0, thirdResponse)]
make_selections(responses)
My intention in that code is to make it so if the user selects a 1, it will return firstResponse, if the user selects 2 it will return secondResponse, etc.
I am basically just bug testing the code to make sure it produces the appropriate response, hence the "Error man..." string, but for some reason it just loops through the error message without printing the appropriate response string. Why is this?
I know that this code is enumerating the list of tuples and I can call them properly, as I can change the code to the following and get the expected output:
for i, v in enumerate(response):
i += 1 # adds 1 to the index to make list indices correlate to a regular 1,2,3 style list
print i, v
Also, two quick asides before anyone asks:
I know there is currently no way to get out of this while loop. I'm just making sure each part of my code works before I move on to the next part. Which brings me to the point of the tuples.
When I get the code working, a 0 will produce the response message and loop again, asking the user to make a different selection, whereas a 1 will produce the appropriate response, break out of the loop, and move on to the next 'room' in the story... this way I can have as many 'rooms' for as long of a story as I want, the player does not have to 'die' each time they make an incorrect selection, and each 'room' can have any arbitrary amount of options and possible responses to choose from and I don't need to keep writing separate loops for each room.
There are a few problems here.
First, there's no good reason to iterate through all the numbers just to see if one of them matches selection; you already know that will be true if 1 <= selection <= len(response), and you can then just do response[selection-1] to get the v. (If you know anything about dicts, you might be able to see an even more convenient way to write this whole thing… but if not, don't worry about it.)
But if you really want to do this exhaustive search, you shouldn't print out There is an error man after any mismatch, because then you're always going to print it at least twice. Instead, you want to only print it if all of them failed to match. You can do this by keeping track of a "matched" flag, or by using a break and an else: clause on your for loop, whichever seems simpler, but you have to do something. See break and continue Statements, and else Clauses on Loops in the tutorial for more details.
But the biggest problem is that raw_input returns a string, and there's no way a string is ever going to be equal to a number. For example, try '1' == 1 in your interactive interpreter, and it'll say False. So, what you need to do is convert the user's input into a number so you can compare it. You can do that like this:
try:
selection = int(selection)
except ValueError:
print "That's not a number!"
continue
Seems like this is a job for dictionaries in python. Not sure if your assignment allows this, but here's my code:
def make_selections(response):
selection = raw_input('-> ')
print response.get(selection, err_msg)
resp_dict = {
'1':'You chose option one.',
'2':'You chose option two.',
'3':'You chose option three.'
}
err_msg = 'Sorry, you must pick one of these choices: %s'%sorted(resp_dict.keys())
make_selections(resp_dict)
The problem is that you are comparing a string to an integer. Selection is raw input, so it comes in as a str. Convert it to an int and it will evaluate as you expect.
You can check the type of a variable by using type(var). For example, print type(selection) after you take the input will return type 'str'.
def make_selections(response):
repeat = True
while repeat == True:
selection = raw_input('-> ')
for i, v in enumerate(response):
i +=1 # adds 1 to the index to make list indices correlate to a regular 1,2,3 style list
if int(selection) == i:
print v[1]
else:
print "There's an error man, what are you doing?!?!?"

Python input datatype handling

I spent a good hour or more looking for the answer on here. I have found a few things that help, but do not answer my question specifically. I am using Python 3.3.3. I am a novice so please be gentle.
I am trying to create a program that takes a user input, but then I need to do a check to see what datatype that input is, and then based on that datatype take a certain course of action.
Any string besides those found in this list:
valid_help_string_list = ['\'help\'', '\'HELP\'', 'help', 'HELP']
should result in the printing of:
'please enter a valid entry' or something to that effect.
Any integer (over 0 but under 500) should have float() used on it to make the rows line up.
Any float (over 0.0 but under 500.0) is valid.
For the sake of this project I am assuming nobody using this will weigh under 100 lbs or over 500.
Anything not falling within those categories should also yield the same "please enter a valid response" error message to the user.
I think it's simple enough of a project to take on for a novice. The program is meant to allow you to input your weight and then creates a pictogram based on that weight and saves it all on the next open line of the .txt file I have set up for it. Or if you want to see the legend for the pictogram, you should be able to type help in any variation found in that list.
Any help would be much appreciated.
The user input will be a string by default, so we need to check whether it could become an integer or float. As you want to turn the integers in floats anyway, there's no need to do anything complex:
def validate_input(val, min_v=100, max_v=500):
try:
val = float(val)
except ValueError:
print("Not a valid entry")
else:
if not min_v < val <= max_v:
print("Value should be between {} and {}".format(min_v, max_v))
else:
return val
return False
Now your calling loop can read:
while True:
val = input("...")
if val in valid_help_string_list:
# print help
else:
val = validate_input(val)
if val:
break
# use val
Note that this relies on the return from validate_input being either False or a number larger than 0; Python will interpret a zero return as False and not reach the break, so I recommend keeping min_v >= 0.

Categories