Treating index of a list as a integer - python

I'm doing some sample programming challenges to practice for a upcoming competition, and I've found myself stumped on a rather easy challenge.
Basically, the user has to enter x amount of numbers, and I have to return the sum of the numbers. The condition is that every time they enter 0, it means i have to disregard the last number that they entered, so it will not be apart of the sum anymore.
Here is my code:
numbers = []
index = 0
total = 0
k = input("How many numbers would you like to enter? (1- 100000)" + "\n").strip()
for x in range (int(k)):
number = input("Enter a number." + "\n").strip()
numbers.append(number)
if number == '0':
index = numbers.index(number)
numbers.pop([index - 1])
numbers.pop([index])
for y in range (len(numbers)):
for item in numbers:
total += int(item)
print(total)
error on this line:
numbers.pop([index - 1])
It tells me that 'list' object cannot be interpreted as an integer. I originally tried to make it int(index) hoping that it would convert it into an int so i can carry out the subtraction to get the index of the number before it so i can pop it out of the list, but I got the same error message.
Is there any way to use this value as an integer so I can carry out the subtract one. Or is there a different way required to get the index of the number before?

well, in python, one can refer to elements at the end of the list with negative numbers:
>>> l = range(10, 100, 5)
>>> l
[10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]
>>> l[-1]
95
>>> l[-2]
90
and pop will take these negative numbers, so to delete the second to last item in the list is just:
>>> l.pop(-2)
90
>>> l
[10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 95]

What do you think [index - 1] is? It's obviously a list. And that's not an integer. index - 1, without the square brackets, would be an integer. Also, you should check for whether the user's number is 0 before appending it, or the last value in the list will be that 0 rather than the value you need to remove, which just makes for extra work.
There's also a lot of room for improvement in your code, along the lines of making proper use of built-ins and eliminating unnecessary counters:
k = int(input("How many numbers would you like to enter? (1- 100000)\n"))
result = []
for i in range(k):
num = int(input("Enter a number.\n"))
if num:
result.append(num)
elif result:
result.pop(-1)
print(sum(result))

It should be numbers.pop(index - 1)
What you have to do is to pass the integer value of the index that needs to be popped, rather than passing a list.

Try this
numbers = []
index = 0
total = 0
k = input("How many numbers would you like to enter? (1- 100000)" + "\n").strip()
for x in range (int(k)):
number = input("Enter a number." + "\n").strip()
numbers.append(number)
if number == '0':
index = numbers.index(number)
numbers.pop(index - 1)
numbers.pop(index)
for y in range (len(numbers)):
for item in numbers:
total += int(item)
print(total)

You are passing a list, when you should pass an int
numbers.pop(index-1)
code:
numbers = []
index = 0
total = 0
k = input("How many numbers would you like to enter? (1- 100000)" + "\n").strip()
for x in range (int(k)):
number = input("Enter a number." + "\n").strip()
numbers.append(number)
if number == '0':
index = numbers.index(number)
numbers.pop(index)
numbers.pop(index-1)
for y in range (len(numbers)):
for item in numbers:
total += int(item)
print(total)
And if I may, this is an easier way of doing it
total = 0
last = 0
k = input("How many numbers would you like to enter? (1- 100000)" + "\n").strip()
for x in range (int(k)):
print("Enter Number")
temp = int(input())
total += temp
if temp == 0:
total -= last
else:
last = temp
print(total)

Related

Replace an item in a list by another item

I have to replace in a list the multiples of 5 by the number + x. For example, if I have the list [1,3,5,7,9,9,11,13,15,17,19,21,23,25,27,29], the result has to be [1,3,5x,7,9,11,13,15x,17,19,21,23,25x,27,29]. I have tried to develop the script but it doesn't work, can anyone help me?
numbers = list (range(1,31))
odds = [number for number in numbers if number % 2 == 1]
print(odds)
for index, value in enumerate(odds):
if value%5==0:
odds[index] = '5x'
print(odds)
We can solve your problem by using the value variable, which stores the current number. We just need to reference this variable when setting the current element to add to "x", like this:
odds[index] = str(value) + "x"
Notice the need to cast value as a string, as we cannot concatinate an integer and a string without creating a touple.
You can make your code much simpler:
numbers = range(1, 31, 2)
res = [str(i) + 'x' if i%5 == 0 else i for i in numbers]
print(res)
Result:
[1, 3, '5x', 7, 9, 11, 13, '15x', 17, 19, 21, 23, '25x', 27, 29]
Explanation:
numbers = range(1, 31, 2)
This creates an iterable with odd numbers from 1 to 29 without having to do:
numbers = list(range(1,31))
odds = [number for number in numbers if number % 2 == 1]
which is redundant. The syntax for the range function is range(start, stop, step), so for odd numbers from 1 to 30, it'll be range(1, 31, 2) which will give 1, 3, 5, 7, and so on.
res = [str(i) + 'x' if i%5 == 0 else i for i in numbers]
I'm assuming you know how to use list comprehensions since you've used it in your code. The above line of code simply searches for a value that is divisible by 5 and adds an x to this value, else it simply adds i to the list.
You can also use f-strings instead of str(i) + x (as Stuart suggests under Jensen's answer):
res = [f'{i}x' if i%5 == 0 else i for i in numbers]

I'm trying to write a Python program to find the number of notes in an integer, but my code isn't working

Look at this image for easier understanding
This is what the python program should do. The notes to use are [500, 200, 100, 50, 20, 10]
Can someone explain what is wrong with my code? I've been sitting here and scratching my head for the longest time.
def note_calculator(num):
notes = [500, 200, 100, 50, 20, 10]
counter = 0
mult = 0
for x in range(6):
enote = notes[x]
if num <= enote:
if num % enote == 0:
mult = num / enote
num = num - (mult * enote)
counter += mult
if num == 0:
break
else:
num = num - enote
counter += 1
if num == 0:
break
else:
continue
return counter
Basically, my method is to put sample notes in a list and iterate through all of them. If the number you input is greater or equal to the first iteration (500) it will then check the divisibility, if there are no remainders, I calculate the multiple. Then I subtract the multiple * the sample note iteration (500) because the program should run until the input (num) is equal to zero. Then I add to the counter, which will tell me the number of notes. If it is not divisible with remainders I simply subtract the first iteration (500) and add it to the counter. This repeats until the last iteration (10)
I know there is an easier and shorter way to do this, but whatever.
Your algorithm works fine, but I noticed two bugs, first one:
if num <= enote: should be if num >= enote:
You want to get enote when it's not bigger than rest amount, not otherwise.
Second, notice that when if num % enote == 0: you correctly take proper amount of enotes, but in else clause you take only one. You should take as much as you can, so do something similar as in if:
counter += num // enote
num = num % enote
And one small thing, your function now returns float (as / operator do so). You can use //, look:
print(type(10/2)) # <class 'float'>
print(type(10//2)) # <class 'int'>
It appears you are looking for the builtin divmod.
notes = [500, 200, 100, 50, 20, 10]
x = 880
s = 0
for n in notes:
q,r = divmod(x,n)
x = r
s += q
print(s)
Here is how I would implement it (Python 3):
def note_calculator(num):
counter = 0
for note in [500, 200, 100, 50, 20, 10]:
counter += num // note
num %= note
return counter
In Python 2, you can just replace the // with a /.
You can simplify it like this...
from time import time
start = time()
def note_calculator(num):
notes, count= [500, 200, 100, 50, 20, 10], 0
for note in notes:
if note <= num:
multiplier = num // note
num -= note*multiplier
count += multiplier
return count
print(note_calculator(880))
print(note_calculator(1000))
end = time()
print(f"Time Taken : {end-start}")
Output:-
6
2
Time Taken : 3.695487976074219e-05

Python coding using collatz conjecture

I am new at coding and i am trying to do a collatz conjecture.
I think i already made it by i cant code a way to count how much "steps" it takes to the 1.
This is the code i already did.
n = int(input("Enter a number!"))
def lothar(n):
print(n)
if n == 1:
return i
if n % 2 == 0:
n = n / 2
else:
n = ((n*3) + 1)
return lothar(n)
print(lothar(n))
I want to count using a while structure.
For example: in number 4 , it takes 3 steps.
4
2
1.
There's a few ways to count the steps, but I've gone with removing the recursion and using a loop instead:
n = int(input("Enter a number: "))
def lothar(n):
steps = [n]
while n > 1:
if n % 2 == 0:
n = n // 2
else:
n = ((n*3) + 1)
steps.append(n)
return steps
sequence = lothar(n)
print(sequence)
print(str(len(sequence)-1) + " step(s)")
That will return the sequence, which then means we can display the sequence and also output the amount of steps (i.e. the length of the sequence minus one).
For example:
Enter a number: 9
[9, 28, 14, 7, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1]
19 step(s)
Put the while loop into the function, and give a count variable for counting.
n = int(input("Enter a number!"))
count = 1
def lothar(n,count):
while n != 1:
if n % 2 == 0:
count += 1
n = n / 2
else:
count += 1
n = ((n*3) + 1)
return count
print(lothar(n,count))
Because the result you want is to include 4, count will be added one more time, but if you want to count the number of loops, you should set count to 0 for calculation.

Complete n-Digit Factor

I Was trying a problem but my time complexity is very high. Is there any way to reduce my time complexity. The Question Below with my code.
A number is said to be a complete ‘n’ digit factor, if it is a factor
of all ‘n’ digit numbers when concatenated (joined to right) to
itself.
For example, 7 is a complete 3-digit factor as it divides all three
digit numbers from 100 to 999 when concatenated to itself (i.e.
100100, 101101,102102, ... ..., 998998, 999999).
Given the value of n and m(Max Value to be checked), write a code to
generate all numbers from 2 to m (both inclusive) that are complete
n-digit factor and print ‘No complete factors’ otherwise. For example,
if n is 3 and m is 15 then print 7, 11, 13
N = int(input()) #No Of Digits
M = int(input()) #Max Value to be Checked
#Im Assuming Max Value will be less than or equal to 9
Nu = '100000000'
NuN = '9'*N
NuM_1 = int(Nu[:N])
NuM_2 = int(NuN)
Lis = [int(str(i)*2) for i in range(NuM_1,NuM_2+1)]
Count = 0
Res = []
for i in range(2,M+1):
Count = 0
for j in Lis:
if(j%i==0):
Count += 1
if(Count==len(Lis)):
Res.append(i)
if(len(Res)!=0):
for i in Res:
print(i)
You're attacking the problem from the functional definition, rather than analyzing the numerical properties of that definition.
Concatenating an n-digit number to itself is the same as multiplying by 10^n + 1. For instance, doing this with 3-digit numbers is equivalent to multiplying each by 10^3 + 1, or 1001.
A number divides all such integers iff that number divides the multiplier. Therefore, you can drop this massive iteration and check; simply factor 10^n + 1.
For instance, 1001 factors into 7 * 11 * 13; from there, you can generate the seven needed integers in the answer: 7, 11, 13, 77, 91, 143, 1001.
There are many available factoring programs; a simple search will find you that code.
Try this variation, using a break, and a faster creation of Lis :
N = int(input("Enter N: ")) #No Of Digits
M = int(input("Enter M: ")) #Max Value to be Checked
#Im Assuming Max Value will be less than or equal to 9
Nu = '100000000'
NuN = '9'*N
NuM_1 = int(Nu[:N])
NuM_2 = int(NuN)
Lis = [i + (i * (10**N)) for i in range(NuM_1, NuM_2+1)]
Res = []
for i in range(2,M+1):
for j in Lis:
if j%i:
break
else:
Res.append(i)
print(Res)

Finding Avg of all 2-Digit in a list

I'm trying to find the avg of list but only when n >= 10 (two digit numbers, my original list is limited to 100).
Here's what I have right now:
# Calculate average of all two-digit numbers (10-99)
grade_list = [10, 11, 12, 13, 14, 15]
def calcAvg(grade_list):
while n > 10:
total = sum(grade_list)
n = total % len(grade_list)
print_list = n
return print_list
I get that I have to find the total sum of the list when n > 10 and then dividing by the length (only > 10, my original list has single digit elements, so I'd like to avoid them).
But when I run it, I get an error saying: local variable 'n' referenced before assignment
Any help on how to structure this function to achieve the end results (sum/total of only 2-digit elements = avg)
Thanks!
I'd either collect the good grades and use sum/len, or use the mean function:
>>> grade_list = [1, 2, 10, 11, 12, 13, 14, 15]
>>> good = [g for g in grade_list if g > 10]
>>> sum(good) / len(good)
13.0
>>> import statistics
>>> statistics.mean(g for g in grade_list if g > 10)
13.0
def calcAvg(grade_list):
my_list = []
total, count = 0,0
for n in grade_list:
if 10 <= n <= 99:
total += n
if not total:
return None
return total/count
Here is a clean way of doing it:
def calc_avg(lst):
filtered_lst = filter(lambda x: 10 < x < 100, lst)
return sum(filtered_lst) / len(filtered_lst)
So you should use a for loop instead of a while loop. Instead of having two for loops and making a new list, you could just account for the sum inside the first for loop. I demonstrate this below.
def calcAvg(grade_list):
sum = 0;
count = 0;
for n in grade_list:
if 10 <= n <= 99:
sum = sum + n
count = count + 1
return sum/count
I think you should manually go over the code step by step and try to understand what is wrong. Meanwhile this may give you some hints
# Calculate average of all two-digit numbers (10-99)
def calcAvg(alist):
count=total=0
for i in alist:
if 9 < i < 100:
total += i
count += 1
return total/count
Since Python 3.4 there is a statistics module.
So you just need to filter out numbers in range <10,100), for example with a list comprehension, and then pass this filtered list to the mean function. Simple as that.
from statistics import mean
numbers = [1, 20, 30, 50]
mean([n for n in numbers if n >= 10 and n < 100])
>>> 33.333333333333336
You could do this fairly simply with a list comprehension
>>> grades = [1, 2, 10, 11, 12, 13, 14, 15, 120, 122, 320]
>>> lst = [v for v in grades if 10 <= v < 100]
>>> sum(lst)/len(lst)
12

Categories

Resources