what is the mistake in the while/for loop? - python

This is the output using the wrong for/while-loop operation:
current value is 60
current value is 120
total value is 120
This is what I would like it to be:
current value is 10
current value is 30
total value is 30
prices = [10, 20, 30]
total = 0
steps = 0
step_limit = 2
while steps < step_limit:
steps +=1
for i in prices:
total += i
print(f'current value is {total}')
print(f'total value is {total}')

If you want to add each element from the list, the problem that arises here is in the following part of your code:
for i in prices:
total += i
This means that you iterate through each element inside the list and add it to the total (10+20+30). This is done 2 times, so the total will be 120.
You have to replace that part of the code with something that accesses only one element at a time. For instance:
total += prices[steps]
If you desire to add the last element and display the total straight away with it, you can add the last price outside of the while loop right before the message display at the end:
total += prices[steps]
print(f'total value is {total}')

Related

How can I improve the time complexity of this algorithm for finding the max stock price?

I am currently passing the sample tests and 2 of the other 10 cases so 4 out of 12. However, I don't make it through all of the data. I am getting a Terminated due to timeout error which means that my solution isn't fast enough.
def stockmax(prices):
total = 0
for index, price in enumerate(prices):
if index < len(prices) - 1:
section = max(prices[index+1:])
if prices[index] < section:
total += section - prices[index]
return total
I tried to do everything in only one loop. But how exactly can speed this type of question up. I also tried to cut some lines of the code but it is equally as inefficient.
def stockmax(prices):
total = 0
for index, price in enumerate(prices):
if index < len(prices) - 1 and prices[index] < max(prices[index+1:]):
total += max(prices[index+1:]) - prices[index]
return total
Though it passes the same amount of test cases.
I also tried to use heapq but it passes the same test cases and fails due to time.
def stockmax(prices):
total = 0
for index, price in enumerate(prices):
if index < len(prices) - 1:
section = heapq.nlargest(1,prices[index+1:])[0]
if prices[index] < section:
total += section - prices[index]
return total
https://www.hackerrank.com/challenges/stockmax/topics/dynamic-programming-basics
for details on the problem.
https://hr-testcases-us-east-1.s3.amazonaws.com/330/input09.txt?AWSAccessKeyId=AKIAJ4WZFDFQTZRGO3QA&Expires=1538902058&Signature=3%2FnfZzPO8XKRNyGG0Yu9qJIptgk%3D&response-content-type=text%2Fplain
for a link of some test cases but will expire after a while.
Problem
Your algorithms have become so good at predicting the market that you now know what the share price of Wooden Orange Toothpicks Inc. (WOT) will be for the next number of days.
Each day, you can either buy one share of WOT, sell any number of shares of WOT that you own, or not make any transaction at all. What is the maximum profit you can obtain with an optimum trading strategy?
For example, if you know that prices for the next two days are prices = [1,2], you should buy one share day one, and sell it day two for a profit of 1. If they are instead prices = [2,1], no profit can be made so you don't buy or sell stock those days.
Function Description
Complete the stockmax function in the editor below. It must return an integer that represents the maximum profit achievable.
stockmax has the following parameter(s):
prices: an array of integers that represent predicted daily stock prices
Input Format
The first line contains the number of test cases t.
Each of the next t pairs of lines contain:
The first line contains an integer n, the number of predicted prices for WOT.
The next line contains n space-separated integers prices [i], each a predicted stock price for day i.
Constraints
1 <= t <= 10
1 <= n <= 50000
1 <= prices [i] <= 100000
Output Format
Output lines, each containing the maximum profit which can be obtained for the corresponding test case.
Sample Input
3
3
5 3 2
3
1 2 100
4
1 3 1 2
Sample Output
0
197
3
Explanation
For the first case, you cannot obtain any profit because the share price never rises.
For the second case, you can buy one share on the first two days and sell both of them on the third day.
For the third case, you can buy one share on day 1, sell one on day 2, buy one share on day 3, and sell one share on day 4.
Clearly, for any price we can buy, we would want to sell it at the highest price. Fortunately, we are given that highest price. So, iterating backwards, we know the highest future price seen at any point we visit in our travel "back in time."
Python code:
def stockmax(prices):
n = len(prices)
highest = prices[n - 1]
m = [0] * n
# Travel back in time,
# deciding whether to buy or not
for i in xrange(n - 2, -1, -1):
# The most profit buying stock at this point
# is what we may have made the next day
# (which is stored in m[i + 1])
# and what we could make if we bought today
m[i] = m[i + 1] + max(
# buy
highest - prices[i],
# don't buy
0
)
# Update the highest "future price"
highest = max(highest, prices[i])
return m[0]
If you can use Numpy, then something similar to the below should be rather quick (I believe it's the same idea as the answer from #גלעד ברקן).
import numpy as np
with open('.../input09.txt') as fd:
numtests = int(fd.readline().strip())
counter = 0
numvals = 0
vals = None
steps = None
for line in fd:
if (counter % 2 == 0) :
numvals = int(line.strip())
else:
vals = np.fromstring(line, dtype=int, sep=' ', count=numvals)
assert len(vals) == numvals
cum_max = np.maximum.accumulate(vals[::-1])
np.roll(cum_max, -1)
cum_max[len(cum_max) - 1] = 0
delta = (cum_max - vals)
print('#', counter + 1, 'sum:', np.sum(delta * (delta > 0)))
counter += 1
it runs almost instantly on tests from the input09.txt.
Here is my solution written in ruby.
The solution obtained perfect score.
def solution(a)
gain = 0
i = a.count - 1
min = false
mi = false
while i > 0
s = a.delete_at(i)
unless min
mi = a.index(a.min)
min = a[mi]
end
g = s - min
gain = g if g > gain
i -= 1
min = false if i == mi
end
gain
end

subtract n values from input python

I haven't found anything even relevant to my question, so i may be asking it wrong.
I am working on an exercise where I am given sequential values starting at 1 and going to n, but not in order. I must find a missing value from the list.
My method is to add the full 1 => n value in a for loop but I can't figure out how to add n - 1 non-sequential values each as its own line of input in order to subtract it from the full value to get the missing one.
I have been searching modifications to for loops or just how to add n inputs of non-sequential numbers. If I am simply asking the wrong question, I am happy to do my own research if someone could point me in the right direction.
total = 0
for i in range (1 , (int(input())) + 1):
total += i
print(total)
for s in **?????(int(input()))**:
total -= s
print(total)
sample input:
5
3
2
5
1
expected output: 4
To fill in the approach you're using in your example code:
total = 0
n = int(input("How long is the sequence? "))
for i in range(1, n+1):
total += i
for i in range(1, n):
total -= int(input("Enter value {}: ".format(i)))
print("Missing value is: " + str(total))
That first for loop is unnecessary though. First of all, your loop is equivalent to the sum function:
total = sum(range(1,n+1))
But you can do away with any iteration altogether by using the formula:
total = int(n*(n+1)/2) # division causes float output so you have to convert back to an int
I don't know if you are supposed to create the initial data (with the missing item), so I added some lines to generate this sequence:
import random
n = 12 # or n = int(input('Enter n: ')) to get user input
# create a shuffled numeric sequence with one missing value
data = list(range(1,n+1))
data.remove(random.randrange(1,n+1))
random.shuffle(data)
print(data)
# create the corresponding reference sequence (without missing value)
data2 = list(range(1,n+1))
# find missing data with your algorithm
print("Missing value =", sum(data2)-sum(data))
Here is the output:
[12, 4, 11, 5, 2, 7, 1, 6, 8, 9, 10]
Missing value = 3

Print requested number of entries based off total (reverse ordering)

I am trying to write a function that will print the number of requested records based off a given total in reverse order (zero-based). If 0 is passed in as the number of requested records, the total is used.
Examples:
total=3
numRequested=3
rec00000002
rec00000001
rec00000000
total=2 numRequested=1
rec00000001
While it works for some cases, I have run into an issue when the numRequested is less than the total and nears 0. Instead of the above results, I get the following:
total=2 numRequested=1
rec00000000
Here is my attempt:
def printExpBuf(total, numRequested):
# check if we want all entries
if numRequested == 0:
numRequested = total
# skip over entries we don't need
while (total > numRequested):
total-=1
# print results
while (total > 0):
print "rec%08d" % (total - 1)
total-=1
I see the problem exists where I am decrementing total by 1, but I am at a loss as to how to fix it. Can someone point me in the right direction?
According to comment -
I am always looking to start at the highest record.
This is not what your code is doing, you are first decreasing total , till it becomes equal to the number of requested records. And then printing out the records.
What you actually want to do is to loop and print records till number of requested records become 0 and then return from the function.
Example -
def printExpBuf(total, numRequested):
# check if we want all entries
if numRequested == 0:
numRequested = total
# print results
while (numRequested > 0 and total > 0):
print "rec%08d" % (total - 1)
numRequested -= 1
total -= 1
You were pretty close, this works.
def print_exp_buf(total, num_requested):
# check if we want all entries
if num_requested == 0:
num_requested = total
# skip over entries we don't need
while (total > num_requested):
total -= 1
# print results
while (total >= 0):
print "rec%08d" % (total)
total -= 1
The issues you had were:
Not decrementing total in the while loop, so the loop would never end.
Printing total - 1 so it would never print the first record.
It looks like what you're trying to do is just print a reverse order list of the record numbers requested. That's a much simpler task than all this stuff with decrementing variables; python has a super-simple loop syntax for this sort of situation:
def printExpBuf(total, numRequested):
if (numRequested == 0) or (numRequested > total):
numRequested = total
for count in range(numRequested, 0, -1):
print "rec%08d" % (count)
then:
printExpBuf(3, 3)
printExpBuf(2, 1)
rec00000003
rec00000002
rec00000001
rec00000001

Python, append within a loop

So I need to save the results of a loop and I'm having some difficulty. I want to record my results to a new list, but I get "string index out of range" and other errors. The end goal is to record the products of digits 1-5, 2-6, 3-7 etc, eventually keeping the highest product.
def product_of_digits(number):
d= str(number)
for integer in d:
s = 0
k = []
while s < (len(d)):
j = (int(d[s])*int(d[s+1])*int(d[s+2])*int(d[s+3])*int(d[s+4]))
s += 1
k.append(j)
print(k)
product_of_digits(n)
Similar question some time ago. Hi Chauxvive
This is because you are checking until the last index of d as s and then doing d[s+4] and so on... Instead, you should change your while loop to:
while s < (len(d)-4):

in python, i have an int and want to substract it from a list

In python: how do I divide an int received by a user from a list while every time it runs in the for loop I need to divide the value I received from the round before in the next round?
This is my code:
a = input('price: ')
b = input('cash paid: ')
coin_bills = [100, 50, 20, 10, 5, 1, 0.5]
if b >= a:
for i in coin_bills:
hef = b - a
print (hef / i), '*', i
else:
print 'pay up!'
Example: a=370 b=500 ---> b-a=130
Now in the loop I will receive (when i=100) 1, and (when i=50) I will receive 2 but I want in the second round (when i=50) to divide 30 (130[=b-a]- 100[=answer of round 1*i]) by 50.
What do I need to change in the code?
Thanks!
You just need to subtract the amount of change you give back at each step from the total amount of change you're returning. It's much easier to see if you change your variable names to something meaningful:
price= int(raw_input('price: ')) # Use int(raw_input()) for safety.
paid= int(raw_input('cash paid: '))
coin_bills=[100,50,20,10,5,1,0.5]
if paid >= price:
change = paid - price
for i in coin_bills:
# Use // to force integer division - not needed in Py2, but good practice
# This means you can't give change in a size less than the smallest coin!
print (change // i),'*',i
change -= (change // i) * i # Subtract what you returned from the total change.
else:
print 'pay up!'
You could also clear up the output a bit by only printing the coins/bills that you actually return. Then the inner loop might look something like this:
for i in coin_bills:
coins_or_bills_returned = change // i
if coins_or_bills_returned: # Only print if there's something worth saying.
print coins_or_bills_returned,'*',i
change -= coins_or_bills_returned * i
OK, I'm assuming that you're trying to calculate change for a transaction using a number of types of bills.
The problem is that you need to keep a running tally of how much change you have left to pay out. I used num_curr_bill to calculate how many of the current bill type you're paying out, and your hef I changed to remaining_change (so it would mean something to me) for the remaining change to pay.
a= input('price: ')
b= input('cash paid: ')
coin_bills=[100,50,20,10,5,1,0.5]
if b>=a:
# Calculate total change to pay out, ONCE (so not in the loop)
remaining_change = b-a
for i in coin_bills:
# Find the number of the current bill to pay out
num_curr_bill = remaining_change/i
# Subtract how much you paid out with the current bill from the remaining change
remaining_change -= num_curr_bill * i
# Print the result for the current bill.
print num_curr_bill,'*',i
else:
print 'pay up!'
So, for a price of 120 and cash paid 175, the output is:
price: 120
cash paid: 175
0 * 100
1 * 50
0 * 20
0 * 10
1 * 5
0 * 1
0.0 * 0.5
One bill for 50 and one for 5 add up to 55, the correct change.
Edit: I'd go more sparingly on the comments in my own code, but I added them here for explanation so that you could more clearly see what my thought process was.
Edit 2: I would consider removing the 0.5 in coin_bills and replacing 1 with 1.0, since any fractional amounts will wind up being fractions of 0.5 anyway.

Categories

Resources