Calling a Value in a List using While Loop - python

is there any way to know if the previous appended value is greater than the newly appended value using while loop
unifarr = []
forwarr = []
while t :
unif = randint(-75, 75) # To move face in every possible angle
forw = randint(-1, 1) # Move every 1 pixel, -1 for back 1 for forward
t.left(unif)
t.forward(forw)
sleep(0.01)
forwarr.append(forw)
unifarr.append(unif)# check if prev. value is < or > than newly appended value
i am using random that appends in an array is there any possible way to check if the previous appended random value is greater than the newly appended value

You can create your base case outside while loop and check whether the newly created number is greater than the base case or not. If greater, you do your stuff and finally set your previous to new number for future iterations. Something like this would do the job:
from random import randint
previous_forv = randint(-75, 75)
previous_unif = randint(-1, 1)
forwarr = [previous_forv]
unifarr = [previous_unif]
while t:
new_forv = randint(-75, 75)
new_unif = randint(-1, 1)
t.left(unif)
t.forward(forw)
sleep(0.01)
if new_forv > previous_forv:
forwarr.append(new_forv)
previous_forv = new_forv
if new_unif > previous_unif:
unifarr.append(new_unif)
previous_unif = new_unif

you can index using negative number to index the list from the other end. i.e with -1 you will get the last value with -2 second last value and so on.
if unif > unifarr[-1]:
print ("is greater")
else:
print ("is not greater")
unifarr.append(unif)
OR
unifarr.append(unif)
if unifarr[-1] > unifarr[-2]:
print ("is greater")
else:
print ("is not greater")

Related

removing the middle member or members from list in python

I have this code. Everything is okay but it is not printing the desired values.
I think something is wrong in calling function but I can't figure it out.
this code is removing the middle element if the list length is odd, or the middle two elements if the length is even.
This is the code,
One_Ten = [1,2,3,4,5,6,7,8,9,10]
def removeMiddle(data:list)-> list:
index = 0
size = len(data)
index = size // 2
if (size % 2 == 0 ):
data = data[:index-1] + data[index+1:]
if (size % 2 == 1):
data.pop(index)
return data
data = list(One_Ten)
removeMiddle(data)
print("After removing the middle element (s):why ", data)
so the desired output should look like
[1,2,3,4,7,8,9,10]
You just need to assign data it's new value,
data = removeMiddle(data)
Altertnately you can me the function inplace by editing the first conditions
if (size % 2 == 0):
data.pop(index)
data.pop(index-1)

how to code in python with the following logic for the roman numeral to integer conversion

I am trying to convert the given roman numerals to just numerals for programming practice, with the following logic (I dont want to change this logic unless its falsely thought of)
Here,
M - 1000, C-100, X-10, V-5, I-1
example :
Input - MCMXCVI
Expected Result - 1996
logic - 1000 + (1000-100) + (100-10) + 5 + 1
index- 1 + (3-2) + (5-4) + 6 + 7
Here i am searching next value from the current value subtracting it if its not greater we are adding it normally.
Here is what i have tried, i could't code it correctly, having spent lot of time, thought to ask out for help.
def roman_numeral(num):
"""
Write a Python class to convert an roman numeral to a integer.
Logic: https://www.rapidtables.com/convert/number/how-roman-numerals-to-number.html
"""
# Input the string
# Map of roman numerals and the corresponding values in a dictionary.
NUMERALS = {1000:'M', 900:'CM', 500:'D', 400:'CD', 100:'C', 90:'XC',
50:'L', 40:'XL', 10:'X', 9:'IX', 5:'V', 4:'IV', 1:'I'}
retval=[]
#Check if each char matches with the dictionary and take the numerical value of the inputed roman
for k in range(len(num)):
for i,j in NUMERALS.items():
if(j==num[k]):
retval.append(i)
elm_count = len(retval)
result=0
result_less=0
result_more=0
ind_tracker=0
#Check if next char from the position of current char if that numerical value is greater then current numerical value.
#If it is greater subtract the current numeric value, if not greater then add it.
for ind,i in enumerate(retval):
print('ind= ',ind,'i= ', i)
#Using this below condition to skip if we have already subtracted the current value from previous value.
if( ind_tracker>ind):
continue
if((ind+1 < elm_count)):
if(i<retval[ind+1]):
#print('result=',result,'retval[ind]=',retval[ind],'retval[ind+1]=', retval[ind+1])
result_less=retval[ind+1]-retval[ind]
print('result_less=',result_less)
ind_tracker=ind+1
else:
result_more+=retval[ind]+result_less
print('result_more=',result_more)
result=result_more
print('final result= ',result)
return result
roman_numeral('MCMXCVI')
The output im getting is
3185
I expect to get
1996
You can change the basic concept. If you reverse the roman numbers and basically start from the right side of the string the whole thing get really simple.
The idea is that if you start from the right, if the next number is bigger or equal to the current number you add the number to the total, if the next number is smaller than the previous one then it is substraced from the total.
roman = "MCMXCVI"
NUMERALS = {1000:'M', 900:'CM', 500:'D', 400:'CD', 100:'C', 90:'XC',
50:'L', 40:'XL', 10:'X', 9:'IX', 5:'V', 4:'IV', 1:'I'}
# reverse roman number letters (basically start from the end
roman_reversed = list(reversed(roman))
#invert the dictionary because we want to translate the letter to numbers not the other way around
inverse_NUMERALS = {v: k for k, v in NUMERALS.items()}
# get the number for each character on its own:
lst_numbers = [inverse_NUMERALS.get(x) for x in roman_reversed]
# loop through the list of numbers
total = 0
previous = 0
for numb in lst_numbers:
if numb >= previous:
total += numb
else:
total -= numb
previous = numb
print(total)
#Out[21]: 1996
You could use (self-implemented):
class RomanToDecimal:
conversion = {'M': 1000, 'CM': 900, 'D': 500, 'CD': 400, 'C': 100, 'XC': 90, 'L': 50, 'XL': 40, 'X': 10, 'IX': 9,
'V': 5, 'IV': 4, 'I': 1}
def convert(self, roman):
total = 0
while len(roman):
before = len(roman)
for key in self.conversion:
if roman.startswith(key):
total += self.conversion[key]
roman = roman[len(key):]
after = len(roman)
if before == after:
raise ValueError("Not a Roman numeral.")
return total
try:
rtd = RomanToDecimal()
assert rtd.convert('M') == 1000
assert rtd.convert('XXXVI') == 36
assert rtd.convert('MMXII') == 2012
assert rtd.convert('MMXX') == 2020
except ValueError as error:
print(error)
I made some minor changes to your existing code!
I added a variable "flag" set to False on default and when result_less, I set it to true
To check we subtracted or not, I used this flag, when the flag is true, i made it false and skipped an iternation.
added a new if statement to check for last number
on result_more, result+=retval[ind], did not used result_less value
on result_less, result+=retval[ind+1]-retval[ind]. in both cases i changed the result value rather than changing more and less values for simplicity.
and BTW, I got rid of those result_more and result_less variables but kept the print statements.
here is your code, modified:
def roman_numeral(num):
"""
Write a Python class to convert an roman numeral to a integer.
Logic: https://www.rapidtables.com/convert/number/how-roman-numerals-to-number.html
"""
# Input the string
# Map of roman numerals and the corresponding values in a dictionary.
NUMERALS = {1000:'M', 900:'CM', 500:'D', 400:'CD', 100:'C', 90:'XC',
50:'L', 40:'XL', 10:'X', 9:'IX', 5:'V', 4:'IV', 1:'I'}
retval=[]
#Check if each char matches with the dictionary and take the numerical value of the inputed roman
for k in range(len(num)):
for i,j in NUMERALS.items():
if(j==num[k]):
retval.append(i)
elm_count = len(retval)
result=0
result_less=0
result_more=0
# ind_tracker=0
flag = False
#Check if next char from the position of current char if that numerical value is greater then current numerical value.
#If it is greater subtract the current numeric value, if not greater then add it.
for ind,i in enumerate(retval):
print('ind= ',ind,'i= ', i)
#Using this below condition to skip if we have already subtracted the current value from previous value.
# if( ind_tracker>ind):
# continue
if(flag):
print("Skipped! Already Subracted!")
flag=False
continue
if((ind+1 == elm_count)):
# if last digit is greater than it's previous, the flag will skip this iteration
print('last digit=',retval[ind])
result+=retval[ind]
if((ind+1 < elm_count)):
if(i<retval[ind+1]):
#print('result=',result,'retval[ind]=',retval[ind],'retval[ind+1]=', retval[ind+1])
# result_less=retval[ind+1]-retval[ind]
result+=retval[ind+1]-retval[ind]
print('result_less=',retval[ind+1]-retval[ind])
# ind_tracker=ind+1
flag = True
else:
# result_more+=retval[ind]+result_less
result+=retval[ind]
print('result_more=',retval[ind])
# result=result_more
print('final result= ',result)
return result
roman_numeral('MCMXCVI')

Rolling a roulette with chances and counting the maximum same-side sequences of a number of rolls

I am trying to generate a random sequence of numbers, with each "result" having a chance of {a}48.6%/{b}48.6%/{c}2.8%.
Counting how many times in a sequence of 6 or more {a} occurred, same for {b}.
{c} counts as neutral, meaning that if an {a} sequence is happening, {c} will count as {a}, additionally if a {b} sequence is happening, then {c} will count as {b}.
The thing is that the results seem right, but every "i" iteration seems to give results that are "weighted" either on the {a} side or the {b} side. And I can't seem to figure out why.
I would expect for example to have a result of :
{a:6, b:7, a:8, a:7, b:9} but what I am getting is {a:7, a:9, a:6, a:8} OR {b:7, b:8, b:6} etc.
Any ideas?
import sys
import random
from random import seed
from random import randint
from datetime import datetime
import time
loopRange = 8
flips = 500
median = 0
for j in range(loopRange):
random.seed(datetime.now())
sequenceArray = []
maxN = 0
flag1 = -1
flag2 = -1
for i in range(flips):
number = randint(1, 1000)
if(number <= 486):
flag1 = 0
sequenceArray.append(number)
elif(number > 486 and number <= 972):
flag1 = 1
sequenceArray.append(number)
elif(number > 972):
sequenceArray.append(number)
if(flag1 != -1 and flag2 == -1):
flag2 = flag1
if(flag1 != flag2):
sequenceArray.pop()
if(len(sequenceArray) > maxN):
maxN = len(sequenceArray)
if(len(sequenceArray) >= 6):
print(len(sequenceArray))
# print(sequenceArray)
# print(sequenceArray)
sequenceArray = []
median += maxN
print("Maximum sequence is %d " % maxN)
print("\n")
time.sleep(random.uniform(0.1, 1))
median = float(median/loopRange)
print("\n")
print(median)
I would implement something with two cursors prev (previous) and curr (current) since you need to detect a change between the current and the previous state.
I just write the code of the inner loop on i since the external loop adds complexity without focusing on the source of the problem. You can then include this in your piece of code. It seems to work for me, but I am not sure to understand perfectly how you want to manage all the behaviours (especially at start).
prev = -1
curr = -1
seq = []
maxN = 0
for i in range(flips):
number = randint(1, 1000)
if number<=486:
curr = 0 # case 'a'
elif number<=972:
curr = 1 # case 'b'
else:
curr = 2 # case 'c', the joker
if (prev==-1) and (curr==2):
# If we start with the joker, don't do anything
# You can add code here to change this behavior
pass
else:
if (prev==-1):
# At start, it is like the previous element is the current one
prev=curr
if (prev==curr) or (curr==2):
# We continue the sequence
seq.append(number)
else:
# Break the sequence
maxN = max(maxN,len(seq)) # save maximum length
if len(seq)>=6:
print("%u: %r"%(prev,seq))
seq = [] # reset sequence
seq.append(number) # don't forget to append the new number! It breaks the sequence, but starts a new one
prev=curr # We switch case 'a' for 'b', or 'b' for 'a'

How to check if all elements of array are filled in Python

I am making a To Do List app in Python using Arrays or Lists. I want to check if the array containing all "to-do tasks" is full or not. If it is full I would then inform the user that the list is full. I am still a beginner.
todo_list = ["1.)", "2.)", "3.)", "4.)", "5.)", "6.)", "7.)", "8.)", "9.)", "10.)"]
def addTask(taskName):
'''
this is a global variable to keep track of what index the last task was
placed in.
'''
global x
x = int(x)
num = x + 1
num = int(num)
taskName = str(taskName)
'''
This is what I tried to make the program start from the beginning if the
list was full.
'''
if x > list_length:
x = 0
todo_list[0] = None
todo_list[x] = str(num) + ".) " + taskName
x = x+1
print("Done!")
main()
Are you saying that you've limited the number of possible tasks to 10? and if each one has a task attached then the list should notify the user it's full?
If so, you know that an empty task is "10.)" so at max it's length is 4 (4 characters), so if any items length is less than or equal to 4 then it's empty
for task in todo_list:
if len(task) > 4:
print('Todo list is full')
break
else:
print('Todo list is full')
Can I also advise of a better way to create the todo list? Use a dictionary.
todo_list = {'clean cat':'incomplete', 'buy milk':'complete'}
and to add a new task is easy!
todo_list['learn python'] = 'incomplete'
and to update a task is even easier!
todo_list['clean cat'] = 'complete'
Here is how I would do it:
todo_list = {}
if len(todo_list) == 10:
print('Sorry, list is full!')
else:
task_name = input('Task name: ')
todo_list[task_name] = 'incomplete'
print(todo_list)
You don't have to define todo_list with numbering. Just define the maximum size of todo_list and check if length of todo_list is bigger than maximum size.
todo_list = list()
MAX_SIZE = 10
add_task(taskName:str):
if len(todo_list) >= MAX_SIZE:
# code you want to run when todo_list is full
else:
todo_list.append("{}.) {}".format(len(todo_list)+1, taskName))

I cant get my code to work. it keeps saying: IndexError: List index out of range

My code is using the lengths of lists to try and find a percentage of how many scores are over an entered number.It all makes sense but I think some of the code needs some editing because it comes up with that error code.How can I fix it???
Here is the code:
result = [("bob",7),("jeff",2),("harold",3)]
score = [7,2,3]
lower = []
higher = []
index2 = len(score)
indexy = int(index2)
index1 = 0
chosen = int(input("the number of marks you want the percentage to be displayed higher than:"))
for counter in score[indexy]:
if score[index1] >= chosen:
higher.append(score[index1])
else:
lower.append(score[index1])
index1 = index1 + 1
original = indexy
new = len(higher)
decrease = int(original) - int(new)
finished1 = decrease/original
finished = finished1 * 100
finishedlow = original - finished
print(finished,"% of the students got over",chosen,"marks")
print(finishedlow,"% of the students got under",chosen,"marks")
Just notice one thing:
>>>score = [7,2,3]
>>>len(score) = 3
but ,index of list start counting from 0, so
>>>score[3]
IndexError: list index out of range
fix your row 12 to:
...
for counter in score:
if counter >= chosen:
...
if you really want to get the index and use them:
....
for index, number in enumerate(score):
if score[index] >= chosen:
......
Your mistake is in Line 9: for counter in score[indexy]:
counter should iterate through a list not through an int and even that you are referring to a value that is out of index range of your list:
1 - Remember indexing should be from 0 to (len(list)-0).
2 - You cannot iterate through a fixed value of int.
So, you should change Line 9 to :
for counter in score
But I'm not sure of the result you will get from your code, you need to check out your code logic.
There is a lot to optimize in your code.
index2 is an int, so no need to convert it to indexy. Indizes in Python are counted from 0, so the highest index is len(list)-1.
You have a counter, so why use index1 in for-loop? You cannot iterate over a number score[indexy].
results = [("bob",7),("jeff",2),("harold",3)]
chosen = int(input("the number of marks you want the percentage to be displayed higher than:"))
higher = sum(score >= chosen for name, score in results)
finished = higher / len(results)
finishedlow = 1 - finished
print("{0:.0%} of the students got over {1} marks".format(finished, chosen))
print("{0:.0%} of the students got under {1} marks".format(finishedlow, chosen))

Categories