Looping Based on 2 Value Python - python

i have 2 variable
ex :
compt = 9
first = 3
second = 2
then i want to looping based on compnt length and then change status on or off based on variable first and second
Output that i want :
On
On
On
Off
Off
On
On
On
Off
my current code is:
x,y=0,0
for i in range(0,compt):
if x != first:
print("On")
x+=1
elif x == first and y != second:
print("Off")
but the output from code above is
On
On
On
Off
Off
On
On
On
On
can someone help me to solve my problem , thank you

compt = 9
first = 3
second = 2
for i in range(compt):
max_val = first + second
if i % max_val < first:
print("on")
else:
print("off")
Output:
on
on
on
off
off
on
on
on
off

from itertools import cycle, islice
total = 9
first = 3
second = 2
sequence = ["On" for _ in range(first)] + ["Off" for _ in range(second)]
print(sequence)
result = islice(cycle(sequence), 0, total)
for state in result:
print(state)
output :
['On', 'On', 'On', 'Off', 'Off']
On
On
On
Off
Off
On
On
On
Off

Another variation with itertools:
from itertools import cycle, repeat, chain
compt = 9
first = 3
second = 2
on = repeat("On", first) # ["On", "On", ..]
off = repeat("Off", second) # ["Off", "Off", ..]
for status in cycle(chain(on, off)): # combine on and off and repeat
print(status)
# break when compt is exhausted
compt -= 1
if compt <= 0:
break

You can use %. We have a total first + second possibility. If our i is less than first it means that we are looking for on and if it's more than first we want to print off:
compt = 9
first = 3
second = 2
for i in range(compt):
if i % (first + second) < first:
print("ON")
else:
print("OFF")

try it...
compt = 9
first = 3
second = 2
i=0
while i < compt:
for k in range(0,first):
i += 1
print('on')
if i >= compt:
break
for j in range(0,second):
i += 1
print('off')
if i >= compt:
break

Related

Group string by 3 character to a List

for example, I have string "25037654", and I want to Group the string by 3.
but, since the string is 8 character, and 8 % 3 is not 0. it have remainder. and I want the final List is ["25", "037", "654"], the first Index will only accept the remainder, for example 1 or 2 character
I think this code may satisfy your requirement.
First get the idx of every slice, then cut this string to each substring.
str_num = "25037654"
idx = [len(str_num)%3+3*i for i in range(len(str_num)//3+1)]
print(idx) # [2, 5, 8]
if(idx[0]!=0):
idx = [0]+idx
res = [str_num[idx[i]:idx[i+1]] for i in range(len(idx)-1)]
print(res) # ['25', '037', '654']
One easy way, in this case, is to use f-string:
s = "25037654"
output = f"{int(s):,}".split(',')
print(output) # ['25', '037', '654']
The above won't work if the input is not numeric. Then try:
leading = len(s) % 3
output = ([s[:leading]] if leading else []) + [s[i:i+3] for i in range(leading, len(s), 3)]
Thanks everyone who respond and answer My Question.
after a few moments I post my question. I found the answer LoL
it's the Long Way, my version. thanks Guyss
s = "25037654"
if len(s) % 3 == 2:
fn = s[0:2]
xx = s[2:len(s)]
group = list(map(''.join, zip(*[iter(xx)]*3)))
final = fn + " " + " ".join(group)
elif len(s) % 3 == 1:
fn = s[0:1]
xx = s[1:len(s)]
group = list(map(''.join, zip(*[iter(xx)]*3)))
final = fn + " " + " ".join(group)
elif len(s) % 3 == 0:
group = list(map(''.join, zip(*[iter(s)]*3)))
final = " ".join(group)
print(final) # 25 037 654
t = "25037654555"
i, j = divmod(len(t), 3) # i - int part, j - remainder
print([t[:j]] + [t[j+(i-1)*3:j+i*3] for i in range(1,i+1) ])
Result:
['25', '037', '654', '555']
You can try my version:
s = "25037654"
rem = len(s)%3
lst = []
i = 0
while i < len(s)-2:
if i == 0:
lst.append(s[:rem])
i+=rem
else:
lst.append(s[i:i+3])
i+=3

How do I get the shortest repitition of something in an array?

Let's say you have a list which only has two types of values and goes something like ['t','r','r','r','t','t','r','r','t'] and you want to find the length of the smallest sequence number of 'r's which have 't's at both ends.
In this case the smallest sequence of 'r' has a length of 2, because there is first t,r,r,r,t and then t,r,r,t, and the latter has the smallest number of 'r's in a row surrounded by 't' and the number of 'r's is 2.
How would I code for finding that number?
This is from a problem of trying of going to a play with your friend, and you want to sit as close as possible with your friend, so you are trying to find the smallest amount of taken seats in between two free seats at a play. "#" is a taken seat and a "." is a free seat. you are given the amount of seats, and the seating arrangement (free seats and taken seats), and they are all in one line.
An example of an input is:
5
#.##.
where there are two taken seats(##) in between two free seats.
Here is my code which is not working for inputs that I don't know, but working for inputs I throw at it.
import sys
seats = int(input())
configuration = input()
seatsArray = []
betweenSeats = 1
betweenSeatsMin = 1
checked = 0
theArray = []
dotCount = 0
for i in configuration:
seatsArray.append(i)
for i in range(len(seatsArray)):
if i == len(seatsArray) - 1:
break
if seatsArray[i] == "." and seatsArray[i+1] == ".":
print(0)
sys.exit()
for i in range(0,len(seatsArray)):
if i > 0:
if checked == seats:
break
checked += 1
if seatsArray[i] == "#":
if i > 0:
if seatsArray[i-1] == "#":
betweenSeats += 1
if seatsArray[i] == ".":
dotCount += 1
if dotCount > 1:
theArray.append(betweenSeats)
betweenSeats = 1
theArray = sorted(theArray)
if theArray.count(1) > 0:
theArray.remove(1)
theArray = list(dict.fromkeys(theArray))
print(theArray[0])
This is a noob and a !optimal approach to your problem using a counter for the minimum and maximum sequence where ew compare both and return the minimum.
''' create a funciton that
will find min sequence
of target char
in a list'''
def finder(a, target):
max_counter = 0
min_counter = 0
''' iterate through our list
and if the element is the target
increase our max counter by 1
'''
for i in x:
if i == target:
max_counter += 1
'''min here is 0
so it will always be less
so we overwrite it's value
with the value of max_counter'''
if min_counter < max_counter:
min_counter = max_counter
'''at last iteration max counter will be less than min counter
so we overwrite it'''
if max_counter < min_counter:
min_counter = max_counter
else:
max_counter = 0
return min_counter
x = ['t','r','r','r','t','t','r','r','t','t','t','r','t']
y = 'r'
print(finder(x,y))
Create a string from list and then search for pattern required and then count r in the found matches and then take min of it
Code:
import re
lst = ['t','r','r','r','t','t','r','r','t']
text = ''.join(lst)
pattern = '(?<=t)r+(?=t)'
smallest_r_seq = min(match.group().count('r') for match in re.finditer(pattern, text))
print(smallest_r_seq)
Output:
2

Trying to find same digits in a row [duplicate]

This question already has answers here:
Longest sequence of consecutive duplicates in a python list
(4 answers)
Closed 2 years ago.
Im trying to find the biggest series of digit in a row in a list which i can input. And im doing this way:
list = []
count_max_numbers = 0
while True:
x = int(input('число: '))
if x == 0:
break
list.append(int(x))
max_number = max(list)
for i in list:
if i != max_number:
pass
else:
count_max_numbers += 1
current_result = 0
max_result = 0
last_seen = list[0]
longest_digit = 0
for i in list:
if i == last_seen:
current_result += 1
else:
if current_result > max_result:
max_result = current_result
longest_digit = i
last_seen = i
current_result = 1
if current_result > max_result:
max_result = current_result
longest_digit = i
print(f'{list}')
print(f'max number: {max_number} reapeted{count_max_numbers} times')
print(f'the biggest series: {longest_digit} repeated {max_result} times')
this works only with first digit in a list. But i need to work it with whole list.
For example if input (1,2,3,3,3,3,5,55)
It need to get output: the biggest series: 3 repeated 4 times
I still have a problem with output of {longest_digit} it's incorrect
Try this:
mylist = [1,2,3,3,3,3,5,55]
val_holder = {}
for val in mylist:
if val not in val_holder.keys():
val_holder[val] = 1
else:
val_holder[val] += 1
max_key = max(val_holder, key=val_holder.get)
print(max_key)
My aproach to this will be using dictionary
lst = [1,2,3,3,3,3,5,55]
dict = {}
for val in lst:
if val not in dict.keys():
dict[val] = 1
else:
dict[val] = dict[val] + 1
Once we get the dictionary we sort this using the value
sorted_dict = sorted(dict.items(), key=lambda keyVal: keyVal[1], reverse=True)
print(dict[0][0])
Here's a simple algorithm:
Initialize longest = None, longest_digit = None, current = 0, previous_digit, and current_digit = None.
Then, for each item in the list:
If the item is equal to current_digit, increment current by one.
Otherwise:
(A) If current > longest, set longest = previous_digit and longest_digit = item
(B) Then, reset current to 1 and current_digit to item
Set previous_digit to item
At the end of the list, also do step (A) above.
Now you should have the answer in longest (4) and longest_digit (3)

sequence of repeated values in a list

I have problems with a program, I hope someone can help me to fix this. Basically I have a random generated list with 20 values, and I want to place between brackets the values that are repeated (for example if the list is [1,2,2,4,5] it should display 1 ( 2 2 ) 4 5 )
Now here's my code that works only if there is no repeated value in the end, because the list index goes out of range. How can I fix this?
from random import randint
lanci = []
for i in range(20):
x = randint(1,6)
lanci.append(x)
print(lanci)
i=0
while i < len(lanci)-1):
if lanci[i] == lanci[i+1]:
print("(",end=" ")
print(lanci[i],end=" ")
while lanci[i]==lanci[i+1]:
i = i + 1
print(lanci[i],end=" ")
print(")",end=" ")
else:
print(lanci[i],end=" ")
i = i + 1
Alternatively to your more manual approach, you could use itertools.groupby to group equal values in the list and then enclose those in parens:
>>> import random, itertools
>>> lst = [random.randint(1, 5) for _ in range(20)]
>>> tmp = [list(map(str, g)) for k, g in itertools.groupby(lst)]
>>> ' '.join(g[0] if len(g) == 1 else "(" + " ".join(g) + ")" for g in tmp)
'5 4 1 2 1 4 (5 5) 4 5 1 5 4 3 (5 5) 3 (5 5 5)'
Not the pretiest but will do it:
from random import randint
from itertools import groupby
lanci = [randint(1,6) for _ in range(20)]
result = [tuple(v) for _, v in groupby(lanci)]
print(*[i[0] if len(i) == 1 else '('+' '.join(map(str, i))+')' for i in result], sep=' ')
#(2 2) 3 5 3 1 5 4 6 2 1 4 6 4 (5 5) 3 6 3 4
Just check for "last element" before your inner while loop.
from random import randint
lanci = []
for i in range(20):
x = randint(1,6)
lanci.append(x)
print(lanci)
i=0
while i < len(lanci)-1):
if lanci[i] == lanci[i+1]:
print("(",end=" ")
print(lanci[i],end=" ")
while (i+1 < len(lanci)) and (lanci[i]==lanci[i+1]):
i = i + 1
print(lanci[i],end=" ")
print(")",end=" ")
else:
print(lanci[i],end=" ")
i = i + 1
convert the list of number to a string then you can use this function.
split it if you need the list back again.
def add_brackets(string):
_character, _index = None, 0
_return_string = ''
for i, c in enumerate(string+ ' '):
if _character is None or _character != c :
if len(string[_index:i])>1:
_return_string+='(' + string[_index: i] + ')'
else:
_return_string+=string[_index: i]
_character, _index = c, i
return _return_string
This is another option using just basic list:
def group_consecutives(lst):
res, sub, memo = [None], [], None
lst.append(memo)
for x in lst:
if memo == x:
sub.append(memo)
if res[-1] != sub: res.append(sub)
else:
sub.append(memo)
if memo and not len(sub) > 1: res.append(memo)
memo, sub = x, []
return res[1:]
print(group_consecutives(lanci))

Random Simulation of 20 Die Throws

Trying to simulate 20 dice throws randomly, the code needs to enclose with parenthesis a value that is the same, the parenthesis appear, but I am missing something on my formula, any advise can greatly help, eg:
1 ( 4 1 ) 2 3 6 1 4 3 2 6 6 6 5 6 2 1 3 5 3 # incorrect
1 4 1 2 3 6 1 4 3 2 ( 6 6 6 ) 5 6 2 1 3 5 3 # this is a correct example
def main():
exampleList = [ ]
for i in range(20):
exampleList.append(randint(1, 6))
print(exampleList)
print(list(range(0,20)))
max_count = 0
run_count = 0
matched = False #inRun = False
# find max run
for rollValue in exampleList:
#print(rollValue)
if run_count == 19:
print()
else:
print("-------")
print("Roll Value %s" % exampleList[run_count])
print("Position %s" % run_count)
print("Next Roll value %s" % exampleList[run_count + 1])
if exampleList[run_count] == exampleList[run_count + 1]:
matched = True
print("------->>>matched")
else:
matched = False#inRun = False
run_count += 1
if rollValue < 19:
if exampleList[rollValue] == exampleList[rollValue + 1]:
run_count += 1
if matched == False:
matched == True
run_count = rollValue
else:
matched = False
if run_count > max_count:
run_count = 1
# print sequence
for rollValue in range(20):
if rollValue == run_count:
print("(", exampleList[rollValue], end = " ")
elif rollValue == run_count + max_count + 1:
print(exampleList[rollValue], ")", end = " ")
else:
print(exampleList[rollValue], end = " ")
main()
Here is a solution using regex. This creates a string out of the dice rolls, then finds repeating digits and uses re.sub to add parenthesis.
import re
import random
rolls = ''.join(map(str, [random.choice(range(1, 7)) for _ in range(20)]))
rolls = ' '.join(re.sub(r'(\d)(\1+)', r'(\1\2)', rolls))
print(rolls)
A couple sample runs:
4 1 4 3 4 6 5 2 3 ( 5 5 ) 1 6 4 3 5 2 5 ( 4 4 )
2 ( 1 1 ) 4 1 ( 5 5 ) ( 3 3 ) 6 2 ( 1 1 ) 5 1 4 3 4 ( 5 5 )
Regex explanation:
( // start of matching group 1
\d // matches a single digit
) // end of matching group 1
( // start of matching group 2
\1+ // matches group 1, 1 or more times
) // end of matching group 2
This adds the parenthesis as part of the list:
#!/usr/bin/python
import sys
from random import randint
# add parenthesis as part of the list
def main():
exampleList = [ ]
previous = -1
opened = False
for i in range(20):
roll = randint(1, 6)
if roll == previous:
if not opened:
exampleList.insert(-1, '(')
opened = True
else:
if opened:
exampleList.append(')')
opened = False
exampleList.append(roll)
previous = roll
if opened:
exampleList.append(')')
for item in exampleList:
sys.stdout.write('{0} '.format(item))
sys.stdout.write('\n')
if __name__ == '__main__':
main()
Examples:
( 2 2 ) 4 5 1 2 1 ( 6 6 ) 1 6 1 4 1 ( 6 6 ) 1 6 2 4
2 ( 6 6 ) ( 1 1 ) 3 2 1 ( 4 4 ) 1 2 5 4 1 5 3 ( 5 5 5 )
There are a number of issues with your code, so it was just quicker to rewrite the whole thing.
def main():
example_list = []
for _ in range(20):
example_list.append(random.randint(1, 6))
inside = False
for index in range(len(example_list)):
try:
if inside:
if example_list[index] != example_list[index + 1]:
print("%d )" % example_list[index], end=" ")
inside = False
else:
print(example_list[index], end=" ")
else:
if example_list[index] == example_list[index + 1]:
print("( %d" % example_list[index], end=" ")
inside = True
else:
print(example_list[index], end=" ")
except IndexError:
print("%d" % example_list[index], end=" ")
if inside:
print(")")
else:
print()
As you can see I keep track of whether I'm inside a parenthesis by using a variable. I look to the next number to guess if I should add a closing parenthesis.
The last case is handled by a try-except.
You could also handle each number by looking forward and backward but that'd require you to add some extra condition for the try-except part so this was just
There are various ways to do this, but this is the most similar to what you were doing already. Basically just iterate over the index of your list of rolls. Each number we examine it to see if it is the same as the one before, if yes, then we increment the count and move on. If not then we add however many of that number were in the count to the output. If there was one, we write it out by itself, if more, in parenthesis.
exampleList = [randint(1, 6) for i in range(20)]
# the current number that could be a potential sequence
current = exampleList[0]
# count for the number of occurences in a sequence (often 1)
count = 1
# The string to outpu
output = ''
# Iterate over the rolls, ignoring the first one
for i in range(1, len(exampleList)):
if exampleList[i] == current:
count += 1
else:
if count > 1:
output += ('(' + count * str(current) + ')')
else:
output += str(current)
current = exampleList[i]
count = 1
# Handle final addition
if count > 1:
output += ('(' + count * str(current) + ')')
else:
output += str(current)
print(output)
Output:
64(66)15253(66)2143454(22)
The logical error is that you're confusing "the index where the run starts" with "the length of the (last) run".
You need a variable like max_run_start_index.
Look at the code:
if rollValue == run_count:
print("(", exampleList[rollValue], end = " ")
Read it back to yourself 'if the index of the next output is equal to the length of the last run, output open bracket before it'.
So if the length of the last run is 3 the longest run starts at index 3?
Surely not...
I'm not a Python coder, so you'll need to fix it yourself...

Categories

Resources