I'm writing a program when the user enter 'apple' at first time, it will print the day 0 and the first element in list. when the user enter 'apple' at second time, it will print the day 1 and the second element. And I want to repeat these for 30 times for 30 days.
Can someone help me with this ?
Thanks
my code:
list_1=["a", "b", "c", "d", "e", "f", "g"]
index = 6
a = 0
i = 0
while True:
a = input("Enter:")
if a == "apple":
if i < 31:
index = (index + 1) % 7
d = list_1[index]
print( "day" ,i, d )
start = input("Start: ")
current = input("Current: ")
i += 1
a += 1
my output:
Enter:apple
day 0 a
Start: 2
Current: 3
day 1 b
Start: 2
Current: 3
day 2 c
Start: 2
Current: 3
...
...
...
Expexted output:
Enter:apple
day 0 a
Start: 2
Current: 3
Enter:apple
day 1 b
Start: 2
Current: 3
...
...
...
...
Enter:apple
day 6 g
Start: 2
Current: 3
Enter:apple
day 7 a
Start: 2
Current: 3
...
...
...
...
Enter:apple
day 30 c
Start: 2
Current: 3
As #aryerez has pointed already pointed out, you're initializing the variable 'i' within the loop hence it'll always get reset to zero in each iteration.
So solution will be keep the initialization line - i = 0 before the while loop.
I do not understand why you're incrementing variable 'a' because it is your input variable.
This looks like it produces what you want. You have to move both i and index outside of the loop.
list_1=["a", "b", "c", "d", "e", "f", "g"]
i = 0
index = 6
while True:
a = input("Enter:")
if a == "apple":
a = 0
if i < 31:
index = (index + 1) % 7
d = list_1[index]
print( "day" ,i, d )
start = input("Start: ")
current = input("Current: ")
i = i + 1
a = a + 1
Here's what the loop that you posted is doing
while(true) #like saying while true is a true statement or while true==true
get user input
if input == 'apple'
then set a=0, i=0, index=6
if i < 31 #which it can't be because we just set it to 0
Do some arithmetic on index #which will always start as 6 because we just assigned it
...
increase i and a by 1 #They will be equal to 1 now
Now go through the loop again
get input
if input=='apple'
set a=0, i=0, and index=6 again
check i<31 #can't be, we just set it to 0
do arithmetic on index #which is equal to 6 again because we just set it.
...
increase a and i by 1
And your loop does this over and over
But if you first assign i and index outside the loop, then we only set them equal to 0 and 6 once.
Related
I am new to python and I've been trying to wrap my head around this code:
stop = int(input())
result = 0
for a in range(4):
print(a, end=': ')
for b in range(2):
result += a + b
if result > stop:
print('-', end=' ')
continue
print(result, end=' ')
print()
When I input 6, the output is
0: 0 1
1: 2 4
2: 6 -
3: - -
why isn't it
0: 0 1
1: 3 4 --> since we're starting out with a = 1 and b = 2 so result is 1 + 2 = 3.
etc
I feel like I'm missing something fundamental.
Value of b will never be 2.
Each iteration of loop will initialise the scope variables. i.e. while looping first loop, value of b will range between 0 & 1.
Whereas, Value of result (a global variable) will be cumulative (value obtained from prev iteration).
iteration
a
b
result
output
1
0
0
0
0: 0..
2
0
1
1
0: 0 1
3
1
0
2
1: 2..
4
1
1
4
1: 2 4
5
2
0
6
2: 6..
6
2
1
9
2: 6 9
7
3
0
12
3: 12..
8
3
1
16
3: 12 16
when a = 0 and b = 1, result = 0 + 0 + 1 = 1,
so, for a = 1 and b = 0, result = 1 + 1 + 0 = 2
when a = 1 and b = 1, result = 2 + 1 + 1 = 4
so, it will print 1: 2 4
How for I get the "rest of the list" after the the current element for an iterator in a loop?
I have a list:
[ "a", "b", "c", "d" ]
They are not actually letters, they are words, but the letters are there for illustration, and there is no reason to expect the list to be small.
For each member of the list, I need to:
def f(depth, list):
for i in list:
print(f"{depth} {i}")
f(depth+1, rest_of_the_list_after_i)
f(0,[ "a", "b", "c", "d" ])
The desired output (with spaces for clarity) would be:
0 a
1 b
2 c
3 d
2 d
1 c
2 d
1 d
0 b
1 c
2 d
1 d
0 c
1 d
0 d
I explored enumerate with little luck.
The reality of the situation is that there is a yield terminating condition. But that's another matter.
I am using (and learning with) python 3.10
This is not homework. I'm 48 :)
You could also look at it like:
0 a 1 b 2 c 3 d
2 d
1 c 2 d
1 d
0 b 1 c 2 d
1 d
0 c 1 d
0 d
That illustrates the stream nature of the thing.
Seems like there are plenty of answers here, but another way to solve your given problem:
def f(depth, l):
for idx, item in enumerate(l):
step = f"{depth * ' '} {depth} {item[0]}"
print(step)
f(depth + 1, l[idx + 1:])
f(0,[ "a", "b", "c", "d" ])
def f(depth, alist):
# you dont need this if you only care about first
# for i in list:
print(f"{depth} {alist[0]}")
next_depth = depth + 1
rest_list = alist[1:]
f(next_depth,rest_list)
this doesnt seem like a very useful method though
def f(depth, alist):
# if you actually want to iterate it
for i,item in enumerate(alist):
print(f"{depth} {alist[0]}")
next_depth = depth + 1
rest_list = alist[i:]
f(next_depth,rest_list)
I guess this code is what you're looking for
def f(depth, lst):
for e,i in enumerate(lst):
print(f"{depth} {i}")
f(depth+1, lst[e+1:])
f(0,[ "a", "b", "c", "d" ])
I have specific issue where, im trying to find solution on inner loop(execute 3 time) and continue outer to process rest of the list in for loop:
strings = ['A','A','A','A','A','A','A','A','A','A','B','B','B','B','B','B','B','B','B','B',\
'A','A','A','A','A','A','A','A','A','A','B','B','B','B','B','B','B','B','B','B']
i=0
for string in strings:
global i
if string == 'A':
while i < 3:
print(string, i)
i+=1
if i==3: continue
elif string== 'B':
while i < 3:
print(string,i)
i+=1
if i==3: continue
# print(string)
Current result:
A 0
A 1
A 2
Expected to have continued over list once the inner loop complete and process from next:
A 0
A 1
A 2
B 0
B 1
B 2
A 0
A 1
A 2
B 0
B 1
B 2
If I understand correctly the logic, you could use itertools.groupby to help you form the groups:
variant #1
from itertools import groupby
MAX = 3
for k,g in groupby(strings):
for i in range(min(len(list(g)), MAX)):
print(f'{k} {i}')
print()
variant #2
from itertools import groupby
MAX = 3
for k,g in groupby(strings):
for i,_ in enumerate(g):
if i >= MAX:
break
print(f'{k} {i}')
print()
output:
A 0
A 1
A 2
B 0
B 1
B 2
A 0
A 1
A 2
B 0
B 1
B 2
variant #3: without import
prev = None
count = 0
MAX = 3
for s in strings:
if s == prev:
if count < MAX:
print(f'{s} {count}')
count += 1
elif prev:
count = 0
print()
prev = s
I would like to transform a list of dates in the following format:
01-02-12
01-03-12
01-27-12
02-01-12
02-23-12
.
.
.
01-03-13
02-02-13
as
1
1
1
2
2
.
.
.
13
14
ie: index each date by month, with respect to year also.
I am not sure how to do this and can't find a similar problem, so advice would be appreciated.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Edit:
In response to #Psidom.
Just an example dataset with made up numbers. In the actual dataset I'm dealing with I've transformed the dates to datetime objects.
dat = pd.read_csv('matchdata-update.csv',encoding = "ISO-8859-1")
dat['Date']=pd.to_datetime(dat['Date'],format='%m-%d-%y% I:%M%p').
Ideally I would like it to count a month , even if it was not observed.
End goal is to index each month and to count number of rows in that insex, so if no month was observed then the number of rows counted for that index would just be 0.
If you want to count the number of rows for every month, this should work:
dat.set_index("Date").resample("M").size()
Here is a different answer using the data as given and producing the answer requested, including 0s for missing monthes.
dates = '''\
01-02-12
01-03-12
01-27-12
02-01-12
02-23-12
01-03-13
02-02-13
'''.splitlines()
def monthnum(date, baseyear):
"Convert date as 'mm-dd-yy' to month number starting with baseyear xx."
m,d,y = map(int, date.split('-'))
return m + 12 * (y-baseyear)
print(monthnum(dates[0], 12) == 1, monthnum(dates[-1], 12) == 14)
def monthnums(dates, baseyear):
"Yield month numbers of 'mm-dd-yy' starting with baseyear."
for date in dates:
m,d,y = map(int, date.split('-'))
yield m + 12 * (y-baseyear)
print(list(monthnums(dates, 12)) == [1,1,1,2,2,13,14])
def num_per_month(mnums):
prev, n = 1, 0
for k in mnums:
if k == prev:
n += 1
else:
yield prev, n
for i in range(prev+1, k):
yield i, 0
prev, n = k, 1
yield prev, n
for m, n in num_per_month(monthnums(dates, 12)):
print(m, n)
prints
True True
True
1 3
2 2
3 0
4 0
5 0
6 0
7 0
8 0
9 0
10 0
11 0
12 0
13 1
14 1
Trying to solve hackerrank problem.
There are plants in a garden. Each of these plants has been added with some amount of pesticide. After each day, if any plant has more pesticide than the plant at its left, being weaker than the left one, it dies. You are given the initial values of the pesticide in each plant. Print the number of days after which no plant dies, i.e. the time after which there are no plants with more pesticide content than the plant to their left.
I have used stacks to solve this problem. Example below:
a = 6 5 8 4 7 10 9
10 > 9 a = 6 5 8 4 7 10 b = 9
7 > 10 a = 6 5 8 4 7 b = 9
4 > 7 a = 6 5 8 4 b = 9
8 > 4 a = 6 5 8 b = 9 4
5 > 8 a = 6 5 b = 9 4
6 > 5 a = 6 5 b = 9 4
after this just make a new list with a = a + b.reverse(). Start the process again and exit when list is sorted in reverse order.
This still is giving me time exceeded. Any idea?
n = int(input())
first_list = input().split()
first_list = [int(i) for i in first_list]
count = 0
second_list = []
data_1, data_2 = 0, 0
while True:
b = []
if sorted(first_list, reverse=True) == first_list:
break
data_1 = first_list.pop()
for i in range(len(first_list)-1):
data_2 = first_list.pop()
if data_1 > data_2:
pass
elif data_1 < data_2:
second_list.append(data_1)
elif data_1 == data_2:
second_list.append(data_1)
second_list.append(data_2)
data_1 = data_2
if len(first_list)>=1 and data_1 < first_list[0]:
first_list.append(data_1)
second_list.reverse()
first_list = first_list + second_list
count += 1
print(count)
Edited code:
n = int(input())
input = [int(i) for i in input().split()]
count, t_length = 0, 0
cmp = input[0]
while True:
length = len(input)
for i in range(1, length):
if input[i] == -1:
t_length += 1
continue
if input[i] > cmp:
cmp = input[i]
input[i] = -1
else:
t_length += 1
cmp = input[i]
if t_length+1 == length:
break
count += 1
cmp, t_length = input[0], 0
print(count)
I agree with Woot4Moo that something doesn't look right, and I suggest you focus more on stack use (instead of doubly linked lists). See this link to the Stock Span problem which helps detail an O(N) solution for tracking differences in a list of prices. This can be extended with a condition for pesticide.
For example, it'd be filling in the gaps of:
import sys
ps = [int(s) for s in list(sys.stdin)[1].strip().split()]
stack = [ps[0]]
max_days = 0
for i in range(1, len(ps)):
days[i] = 1 if ps[i] > ps[i-1] else 0
# TODO - Logic to update days[i]
while len(stack) > 0 and ps[i] <= stack[-1][1]:
(ps_other, days_other) = stack.pop()
stack.append((ps[i], days[i])
max_days = max(max_days, days[i])
print(max_days)
I quickly implemented in O(N^2), and found 80% of tests pass (the rest timing out), so more cleverly using the stack according to the link above should do the job.
import collections
import sys
ps = [int(s) for s in list(sys.stdin)[1].strip().split()]
ps_prev = []
days = 0
while collections.Counter(ps_prev) != collections.Counter(ps):
ps_prev = ps[:]
i = len(ps) - 1
while i > 0:
if ps[i] > ps[i-1]:
ps.pop(i)
i -= 1
days += 1
print(days - 1)
Edit: note that the sketchy sys.stdin use is to cater for the HackerRank test input.
Sorting is N log N and your data structure seems wrong to me. Why would you not use a doubly linked list since the requirement is that it is the left most neighbor. You would simply dereference the pointers that died.