What does this line do? (using num and enumerate) - python

I'm a python beginner, and have been given this code to write out what each line does. Here is the code:
z = [int(input("Enter your nth term sequence ")) for _ in range(12)]
total = sum([num * 8 if i % 2 == 0 else num * 4 for i, num in enumerate(z)])
So, I assume that z is a list, where a user inputs the numbers of the nth term sequence, there are 12 digits which they can enter. The code then finds a sum of the numbers multiplied by 8 if something divided by 2 gives a remainder of 0. I just don't get what ([num * 8 if i % 2 == 0 else num * 4 for i, num in enumerate(z)]) means. I've tried and have attempted to search things up, but it's just too confusing. Please help if possible

The code:
foo = [num * 8 if i % 2 == 0 else num * 4 for i, num in enumerate(z)]
is functionally equivalent to this:
foo = []
for i, num in enumerate(z): # num is element in z, i is index of num
if i % 2 == 0:
foo.append(num*8)
else:
foo.append(num*4)
Then the user calls sum on the result.
Does this answer your question?
EDIT: explain enumerate
You should get used to reading documentation on functions, for example enumerate. After you've read it, if you still don't understand then you should search stackoverflow. For example: A post asking what enumerate is with a good answer
Calling:
for num in z:
i = z.index(num)
# Do stuff
is functionally the same as saying:
for i, num in enumerate(z):
# Do stuff

Lets break this down step by step.
z = [int(input("Enter your nth term sequence ")) for _ in range(12)]
First, your assumption that z is a list is correct. It is generated from a list comprehension. It gets input from a user with input("Enter your nth term sequence ") a total of 12 times using for _ in range(12). So z will be a list of 12 user-input integers (not digits, as it can be any integer, not just 0-9).
Next we have:
total = sum([num * 8 if i % 2 == 0 else num * 4 for i, num in enumerate(z)])
It's immediately clear that we are generating a total from the sum of a list with total = sum([...]). So next we need to figure out the contents of the list generated by the list comprehension.
To make the list comprehension a little bit easier to understand we can add in some parentheses to break up the comprehension into easier to manage parts which we will then handle individually.
(num * 8) if (i % 2 == 0) else (num * 4) for (i, num) in (enumerate(z))
The first three groups are fairly self-explanatory:
num * 8 eight times a number
i % 2 == 0 check if i is even
num * 4 four times a number
So the first half of the list comprehensions returns a value that is eight times a number if i is even or four times that number if it isn't.
So that leaves us with the last half of the list comprehension for i, num in enumerate(z).
Lets discuss enumerate first. Enumerate takes a sequence and numbers each element in that sequence. For example enumerate(['a', 'b', 'c']) would return a list of 2-element tuples [(0, 'a'), (1, 'b'), (2, 'c')].
The for i, num in takes the tuples from enumerate(z) and unpacks each tuple into i and num. So i is the index generated by enumerate and num is the original user input.
TL;DR
z = [int(input("Enter your nth term sequence ")) for _ in range(12)]
total = sum([num * 8 if i % 2 == 0 else num * 4 for i, num in enumerate(z)])
Line 1 gets 12 integers from user input and stores them in z
Line 2 takes those integers, indexes them (starting at 0), and if the index is even multiplies that number by 8, if the index is odd multiplies that number by 4.
Finally line 2 sums all the multiplied user inputs and stores them in total

Well lets break it down. You are storing something to the variable "total".
Then you are taking the Sum of everything inside your parentheses. You run an if statement, saying if i modulus 2(i.e. if it is divisible by two and has no remainder left over) append num(a variable) times 8 to the list z.
else, num times 4 appended to the list z. Its a compact way that they wrote out the statement instead of multiple lines

Related

How to find a specific number in a sequence of number with a constant sum of digit equal to 9 python?

Enter the natural number N (1 <= N <= 1,000,000). Print to the screen the Nth number of the sequence: 9 18 27 36 45 54 63 72 81 90 108 117
(they all have their sum of digit equal to 9)
N = 9+(int(input())-1)*9
def sumnum(N):
sum = 0
while N > 0:
d = N%10
N = N//10
sum += d
sumnum(N)
while sum != 9:
N+=1
sumnum(N)
print(N)
Here's my code and it got this error
TimeLimitError: Stopped on Line 4
Your sumnum function doesn't return anything, so it never changes sum (or any other value) outside of the function. Normally you'd get an error trying to compare an undefined variable, but sum is actually the name of a builtin function, so that's what you're comparing 9 to.
Here's a simple approach: iterate through all numbers in a while loop, and check the sum of each one's digits by converting it to a string and summing the int values of its characters. Each time you find one whose sum is 9, decrement N by one. When it hits zero, print the current number.
>>> N = 12
>>> i = 0
>>> while True:
... i += 1
... if sum(int(d) for d in str(i)) == 9:
... N -= 1
... if N == 0:
... print(i)
... break
...
117
Here's a more code-golf-y approach using a filtered generator with itertools.count() (less efficient for big numbers because it builds a list of the sequence up to N instead of just printing the last element):
>>> import itertools
>>> list(zip(range(N), (i for i in itertools.count() if sum(int(d) for d in str(i)) == 9)))[-1][-1]
117
The millionth such number is 1020011001021000. Found in less than a second by either of these two solutions:
Solution 1
Produce all such numbers with up to 16 digits and then print the N-th (Try it online!):
from itertools import combinations_with_replacement
N = 1_000_000
worths = (10**i for i in range(16))
combs = combinations_with_replacement(worths, 9)
nums = sorted(map(sum, combs))
print(nums[N-1])
With up to 16 digits, the digit positions are worth 10^0 to 10^15. By picking 9 of those position worths (allowing repeats) and adding them, you get the numbers with digit sum 9.
For example, 1020011001021000 came from picking 10^15 once, 10^13 twice, 10^10 once, etc.
Solution 2
Imagine you have nine 1s and you move them around in the digit positions (the "ones" position, "tens" position, "hundreds" position, etc). They all start at the "ones" position, so the first number is 9. Then move one to the "tens" position, so you have the number 18. Move another there and you have 27. And so on. (Try it online!)
N = 1_000_000
digits = [9] + [0] * 15
for _ in range(N-1):
for i, d in enumerate(digits):
if d:
digits[i] = 0
digits[i+1] += 1
digits[0] = d - 1
break
print(int(''.join(map(str, reversed(digits)))))
This worked for me!
def getSum(n):
sum = 0
for digit in str(n):
sum += int(digit)
return sum
for i in range(0, 1000000):
n = i
sum = getSum(n)
if sum == 9:
print(f"{n} -- {sum}")
Numbers whose digits add to 9 are multiples of 9 and vice versa. So the Nth number whose digits add to 9 is N*9. So all you need is this:
N = int(input("Enter N: "))
print (N*9)
You can add range checking for N being between 1 and 1,000,000 if you like.

Python Program to Print all Numbers in a Range Divisible by a Given Number

Python Program to Print all Numbers in a Range Divisible by a Given Numbers
L=int(input()) #L=[2,4,5] take all input at a time to process with range number divisible with give inputs those numbers print output is 20,40 bcuz of 2,4,5 divisible 20, 40 only
L=int(input))
for i in l:
for j in range(1,50):
if j%i==0:
print(j)
I want out put 20,40
Range divisible with all list l
I'm not sure quite sure what you're asking, but I think the gist of it is that you want to print all numbers in a given range that are divisible by a list.
In that case, there is no need to do a type coercion to int on your list, I'm not sure why you did that.
my_list = [2, 4, 5]
# create an empty output list
output = []
# iterate through a range.
for i in range(1, 50):
# create a boolean array that checks if the remainder is 0 for each
# element in my_list
if all([i % j == 0 for j in my_list]):
# if all statements in the boolean list created above are true
# (number is divisible by all elements in my_list), append to output list
output.append(i)
print(output)
First you need to calculate the least common multiple (lcm) of the numbers in the list. Math library in python 3.9 has included a lcm function, so you can use it. If you dont have python 3.9 you can search some solutions.
import math
lcm = math.lcm(2,4,5)
At this point you know that every integer number that you multiply by 20 is going to be divisible by all the numbers in the list (2 * 20=40, 3 * 20=60 ...). So for a range you must divide the maximum range number (in your case 50) and truncate the result.
high = 50
low = 1
n = int(high/lcm)
Make a loop and multiply from 1 to n by the lcm result. Then for each result check if it is equal or higher than the lower range.
for j in range(1,n):
res = j*lcm
if res >= low:
print(res)
values = int(input('enter value count :'))
n = []
for k in range(values):
temp = int(input('enter int value :'))
n.append(temp)
for i in range(1,50):
count = 0
for j in n:
if i%j == 0:
count=count+1
else:
if count==len(n):
print(i,end=',')

How to sum even and odd values with one for-loop and no if-condition?

I am taking a programming class in college and one of the exercises in the problem sheet was to write this code:
number = int(input())
x = 0
y = 0
for n in range(number):
if n % 2 == 0:
x += n
else:
y += n
print(x)
print(y)
using only one "for" loop, and no "while" or "if".
The purpose of the code is to find the sum of the even and the sum of
the odd numbers from zero to the number inputted and print it to the
screen.
Be reminded that at this time we aren't supposed to know about
functions.
I've been trying for a long time now and can't seem to find a way of doing it without using "if" statements to know if the loop variable is even or odd.
Purely for educational purposes (and a bit of fun), here is a solution that does not use any for loops at all. (Granted, in the underlying logic of the functions, there are at least five loops.)
num = list(range(int(input('Enter number: '))))
even = num[::2]
odd = num[1::2]
print('Even list:', even)
print('Odd list:', odd)
print('Even:', sum(even))
print('Odd:', sum(odd))
Output:
Enter number: 10
Even list: [0, 2, 4, 6, 8]
Odd list: [1, 3, 5, 7, 9]
Even: 20
Odd: 25
How does it work?
The input() function returns a str object, which is converted into an integer using the int() function.
The integer is wrapped in the range() and list() functions to convert the given number into a list of values within that range.
This is a convention you will use/see a lot through your Python career.
List slicing is used to get every second element in the list. Given the list is based at zero, these will be even numbers.
Slice the same list again, starting with the second element, and get every second element ... odd numbers.
Link to a nice SO answer regarding slicing in Python.
The simply use the sum() function to get the sums.
for n in range(number):
x += (1 - n % 2) * n
y += (n % 2) * n
You asked for a solution with one loop, but how about a solution with no loop?
It is well known that the sum of the numbers from 1 to n is (n+1)*n/2. Thus, the sum of even numbers is 2 * (m+1)*m/2 with m = n//2 (i.e. floor(n/2)). The sum of odd can then be calculated by the sum of all numbers minus the sum of even numbers.
n = 12345
m = n // 2
e = (m+1)*m
o = (n+1)*n//2 - e
Verification:
>>> e, e==sum(i for i in range(n+1) if i % 2 == 0)
38112102 True
>>> o, o==sum(i for i in range(n+1) if i % 2 == 1)
38105929 True
Note: This calculates the sums for number up to and including n.
for n in range(1,number,2):
x += n
y += n-1
print(y)
print(x)
This code has the same output with the example.
Ternary operator:
for n in range(number):
x += (n,0)[n%2]
y += (0,n)[n%2]
I think you are a beginner. I wouldn't like to confuse you with slicing operators complex implementation.
As you mentioned
The purpose of the code is to find the sum of the even and the sum of
the odd numbers from zero to the number inputted and print it to the
screen.
There is no need to find the initial number is odd/even
And your program is wrong if you want to include the input number in calculating the even/odd sum.
Example
Input
5
Expected Output
6
9
Explanation
Even Sum : 2+4 = 6
Odd Sum : 1+3+5 = 9
Your Output
6 4 (wrong output)
The range() function will exclude the number. It will only iterate from 0 to 4 while the input is 5. so if you want to include 5, you should add 1 to the number while passing it in the range() function.
number = int(input())
x = 0
y = 0
for n in range(number+1):
x += (1 - n % 2) * n #this will add 0 if not even
y += (n % 2) * n #this will add 0 if not odd
print(x)
print(y)
There is also mathematical way:
num = int(input("Enter number:"))
odd = ((num+1)/2)**2
even = num*(num+1)/2 - odd
The sum of the first n odd numbers is n^2. To get count of odd numbers we use (num+1)/2. To get sum of even numbers, we could use similar approach, but I preferred, subtracting odd from the sum of the first n numbers, which is n*(n+1)/2.
Here is my 2cents if we are allowed to use numpy.
import numpy as np
number = int(input())
l = np.array(range(number))
print('odd:',sum(l % 2 * l))
print('even:', sum((1- l % 2) * l))
If you're allowed to use a list
number = int( input() )
counts = [ 0, 0 ]
for n in range( number ):
counts[ n % 2 ] += n
print( counts[ 0 ] )
print( counts[ 1 ] )
There's another way which sums the odd and even indices together in the for loop based on the remainder modulo 2:
number = int(input())
odd = 0
even = 0
for i in range(len(number)):
odd += i * (i % 2)
even += i * ((i + 1) % 2)
print (odd, even)
number = 1000000
x = 0
y = 0
[(x:=x+n, y:=y+(n+1)) for n in range(0,number,2)]
print(f'{x}, {y}')
This uses a list comprehension and the new Python assignment operator.
Sum of first n numbers is n(n+1)/2 (Mathematically derived). So if we know the value of n then we can find the sum of all numbers from 1 to n.
If we find the sum of all odd numbers before n and subratract it from the sum of first n we get he sum of all even numbers before n.
Here's the code:
n = int(input("Enter a number: "))
odd = 0
for i in range(1,n+1,2):
odd += i
even = int(n*(n+1)/2) - odd
print("even:",even,"odd:",odd)

Why does my python program ignore/skip some cases

I'm trying to write a code which does the following:
In the first line, it inputs two space-separated integers, the first presents the length of the list which will be input later, and the second presents an int, called k, which will be needed later on.
In the second line, the list I talked about will be input
The expected output is what meets the following criteria:
number of pairs of ( i , j ), where i<j and ar[ i ]+ar[ j ] is divisible by k.
Problem: I don't know why my code ignores some pairs. I have tried it with many test cases, and it fails 90% of them, by outputting less pairs than expected. I know I am pretty close to the right result, I just don't know what I'm not doing right.
For more precise information about what I want my code to do, kindly check this link (No signup or login needed): https://www.hackerrank.com/challenges/divisible-sum-pairs/problem
Here is my code:
#https://www.hackerrank.com/challenges/divisible-sum-pairs/problem
samples_and_k = [int(x) for x in input().split()]
num_list = [int(y) for y in input().split()]
num_list.sort()
counter =0
for i in range(0, samples_and_k[0]-1):
for j in range(i+1, samples_and_k[0]-1):
if (num_list[i]+num_list[i+1]) % samples_and_k[1] == 0:
counter += 1
print(counter)
Here's an example:
Input:
6 3
1 3 2 6 1 2
Expected output:
5
The output of MY code:
3
The problem is that you subtract 1 when using range():
for i in range(0, samples_and_k[0]-1):
for j in range(i+1, samples_and_k[0]-1):
if (num_list[i]+num_list[i+1]) % samples_and_k[1] == 0:
counter += 1
It should be:
for i in range(0, samples_and_k[0]):
for j in range(i+1, samples_and_k[0]):
if (num_list[i]+num_list[i+1]) % samples_and_k[1] == 0:
counter += 1
It's a common misunderstanding when using range(), as range() is implemented somewhat unintuitively (in my opinion). The last number is not included in the range, so list(range(0, 6)) is equal to [0, 1, 2, 3, 4, 5].

Multiplying every Nth element in a list by M

I have a problem I can't seem to figure out. I am very new to Python and have only been coding for three weeks. Any help is appreciated.
Problem:
We are passing in 3 inputs:
a list of numbers
a multiplier value, M
a value, N
You should multiply every Nth element (do not multiply the 0th element) by M. So if N is 3, you start with the 3rd element, which is index 2.
If there are less than N elements then you should output the unchanged input list.
I can't seem to figure this out. I have tried many different things here. Currently, I have the following, which is not working at all.
Provided:
import sys
M= int(sys.argv[2])
N= int(sys.argv[3])
numbers= sys.argv[1].split(',')
for i in range(0, len(numbers)):
numbers[i]= int(numbers[i])
My Code:
for N in numbers:
if numbers[i] > 0:
total = N * M
print(total)
else:
print(numbers)
Output:
I am not even close to what the output should be. Feeling lost on this. Here is what my code comes to. It looks like they want the output in a list.
Program Failed for Input: 1,2,3,4,5,6 5 3
Expected Output: [1, 2, 15, 4, 5, 30]
Your Program Output:
5
10
15
20
25
30
You could try a list comprehension with slicing.
numbers[N-1::N] = [x * M for x in numbers[N-1::N]]
A more elegant solution using list comprehensions ;)
[item*M if (index and not (index+1)%N) else item for index, item in enumerate(items)]
This solution is based on your original one. A more pythonic one would use for instance, a list comprehension so keep that in mind in the future,
output = [numbers[0]]
if len(numbers) >= N:
for i in range(1,len(numbers)):
if ((i+1)%N) is 0:
output.append(numbers[i]*M)
else:
output.append(numbers[i]);
else:
output = numbers
If N is not larger than the list size, the program constructs a new list of numbers with each Nth number being multiplied by M. This is done with a simple modulo operator. Indexing in Python starts with zero and i iterates through index values but your desired output counts the elements as if starting from 1 - thus i+1 in the modulo. If it is not every Nth - program just append the old value. If the list is shorter than N altogether, it assigns the whole unchanged list to the output list.
will this work for you?
res = []
for num in numbers:
if num > 0:
total = num * M
res.append(total)
if len(res) != len(numbers):
print (numbers)
else:
res.reverse()
print (res)
So after many attempts and bouncing this off of a friend who works as a programmer, I ended up with this that gave me the proper output:
newlist = []
if len(numbers) < N:
newlist = numbers
else:
for i in range(0, len(numbers)):
num = numbers[i]
if (i+1) % N == 0:
newlist.append(num*M)
else:
newlist.append(num)
i+=1
print(newlist)
# Input
import sys
M= int(sys.argv[2])
N= int(sys.argv[3])
# convert strings to integers
numbers= sys.argv[1].split(',')
for i in range(0, len(numbers)):
numbers[i]= int(numbers[i])
# if the length of our list is greater than our supplied value
# loop to multiply(starting at the 3rd position in the list) by M
if len(numbers) > N :
for num in range(2, len(numbers), 3) :
numbers[num] = numbers[num] * M
print(numbers)

Categories