When I call the function it shows nothing? - python-3.x

A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.
Find the largest palindrome made from the product of two 3-digit numbers.
This is my script in python 3.5:
def plin1():
for i in range(1000,1):
for j in range(1000,1):
if str(i*j)==str(i*j)[::-1]:
break
return i*j
print(i,'*',j,'=',i*j)
But when I call this function, nothing is printed. What's wrong?

range(start, stop[, step]) -> range object
range() requires the first argument to be less than the second when step is positive, and step defaults to 1 when range() is called with 2 arguments. Hence the range object yields an empty sequence and the body of the for loop is never entered:
>>> list(range(1000, 1))
[]
However, by specifying a negative value for step, you can get the sequence that you require e.g.:
>>> list(range(10, 1))
[]
>>> list(range(10, 1, -1))
[10, 9, 8, 7, 6, 5, 4, 3, 2]
So in your case you would do this:
for i in range(999, 99, -1):
for j in range(999, 99, -1):
# etc...
which would then iterate over all 3 digit numbers starting at the largest.
Also the use of return is incorrect and it will cause the function to terminate without printing anything. Here is a corrected version:
def plin1():
for i in range(999, 99, -1):
for j in range(999, 99, -1):
if str(i*j) == str(i*j)[::-1]:
return i*j
print(i,'*',j,'=',i*j)
Now the function returns the value only when it finds a palindrome. If there were no palindromes, the function would return None.
Notice, however, that this does not produce the largest palindrome that is the product of two 3 digit numbers. This function returns 580085 which is 995 * 583. But the largest one is 993 * 913 = 906609. You need to figure out which is the largest palindrome across all products, not just the first palindrome found. Here is a generator expression that will produce the required result:
max((i*j,i,j) for i in range(100, 1000) for j in range(100, 1000)
if str(i*j) == str(i*j)[::-1])
Which produces the tuple (906609, 993, 913).
Probably there are optimisations that could be made to reduce the number of calculations.

range with two arguments i, j generates the range from i to j. If i > j then there is no range to generate, and when iterating over that range nothing happens.
Range also takes a "step" parameter, allowing you to set the increment of the range. Perhaps you meant to use that. It would look like this:
for i in range(1, 1000, 1):
# loop body
Note that specifying a step of 1 is redundant, as 1 is the default value for that parameter.
If you want to generate a "do the right thing" range to generate the range from the lesser of (i, j) to the greater, you might write a function like the following:
def dwim_range(i,j):
return range(*sorted((i,j)))
Here you're sorting the tuple (i, j) and then unpacking it with the * operator so that range gets the two items of the tuple, in sorted order.

Related

My second for loop is not working in the below code

nums=[0,5,4,12]
n=len(nums)
temp=1
ans=[]
for i in range(n):
ans.append(temp)
temp*=nums[i]
temp=1
for i in range(n-1,-1):
ans[i]*=temp
temp*=nums[i]
print("yes")
print(ans)
Given an integer array nums, return an array answer such that answer[i] is equal to the product of all the elements of nums except nums[i].
The product of any prefix or suffix of nums is guaranteed to fit in a 32-bit integer.
You must write an algorithm that runs in O(n) time and without using the division operation.
This is a solution for this leetcode question but my second for loop is not executing, and i don't know why.
Using range like this will result in zero iterations because the "step" parameter is 1. So because it is 1 it will think it should go upwards, but n is already above -1, so it should be like
range(n, -1, -1)
also you most probably want
import math
n = [0, 5, 4, 12]
ans = []
for num in n:
temp = n[:] # create a copy
temp.remove(num) # remove the number you are on
ans.append(math.prod(temp)) # use math.prod to multiply the rest together
return ans

Algorithm for calculating the duplicates in a list

The code below prints out the numbers which are duplicated in A.
From my understanding, the for loop goes through each element in the list and turns it into a negative number, though i can not figure out why it does not turn the numbers it prints (which are at at position 0,4,5) negative.
A = [1,2,3,1,3,6,6]
def printRepeating(arr, size):
print("The repeating elements are: ")
for i,x in enumerate(arr):
if arr[abs(arr[i])] >= 0:
arr[abs(arr[i])] = -arr[abs(arr[i])]
print(arr)
else:
print (abs(arr[i]), end = " ")
printRepeating(A,len(A))
The algorithm assumes:
all the elements of the array start as positive numbers, and
all the elements of the array are less than the length of the array.
In your example, since the length of the array is 7, all the elements in the array must be between 1 and 6.
What the algorithm does is change array[k] to negative to indicate that k has been seen. For example, since 1 is the first number seen, array[1] is changed to a negative number. The next time 1 is seen, array[1] is already negative, so 1 must be a duplicate.
If you just want to print the repeated values in the list then why not try this:
A = [1, 2, 3, 1, 3, 6, 6]
def get_repeated_elements(lst):
return list(set((i for i in lst if lst.count(i) > 1)))
print(get_repeated_elements(A))
This function converts the passed array into a generator of duplicated values
and then converts this into a set to filter out duplicates in the generator and then converts this into a list for returning to the caller. This is a far shorter function than the one given.
The algorithm assumes that all entries are strictly positive and smaller than the length of the list. Then, what it does is essentially using the sign of the i-th element to store if it already saw number i. In your example:
A=[1,2,3,1,3,6,6] Take 1
A[1] is positive, i.e. we have not seen it. Make it negative to mark it
A=[1,-2,3,1,3,6,6] Take -2 (stands for 2)
A[2] is positive, i.e. we have not seen it. Make it negative to mark it
A=[1,-2,-3,1,3,6,6] Take -3
A[3] is positive, i.e. we have not seen it. Make it negative to mark it
A=[1,-2,-3,-1,3,6,6] Take -1
A[1] is negative, i.e. we have already seen it. Report it.
A=[1,-2,-3,-1,3,6,6] Take 3
A[3] is negative, i.e. we have already seen it. Report it.
...
The below code can be used to find repeated elements in the list and also unique elements in the list.
from collections import Counter
A = [1,2,3,1,3,6,6]
B = Counter(A)
The below line prints repeated elements.
[k for k, v in B.items() if v > 1]
Output : [1, 3, 6]
The below line prints unique elements.
[k for k, v in B.items() if v == 1]
Output : [2]

create list from list where values only increase by 1

I have the code below that gets the maximum value from a list. It then compares it to the maximum value of the remaining values in the list, and if it is more than 1 higher than the next greatest value, it replaces the original list maximum with 1 higher than the next greatest value. I would like the code to search the entire list and make sure that any value in the list is at most 1 larger than any other value in the list. I know this ins’t the best worded explanation, I hope the example lists below make what I’m trying to accomplish clearer.
for example I don’t want to get a final list like:
[0,2,0,3]
I would want the final list to be
[0,1,0,2]
input:
empt=[0,2,0,0]
Code:
nwEmpt=[i for i in empt if i !=max(empt)]
nwEmpt2=[]
for i in range(0,len(empt)):
if (empt[i]==max(empt))&(max(empt)>(max(nwEmpt)+1)):
nwEmpt2.append((max(nwEmpt)+1))
elif (empt[i]==max(empt))&(max(empt)==(max(nwEmpt)+1)):
nwEmpt2.append(max(empt))
else:
nwEmpt2.append(empt[i])
output:
nwEmpt2
[0,1,0,0]
min_value = min(empt)
empt_set = set(empt)
for i in empt:
nwEmpt.append(min_value + len(list(filter(lambda x: x < i, empt_set))))
This gives e.g. for input empt = [8, 10, 6, 4, 4] output nwEmpt = [6, 7, 5, 4, 4].
It works by mapping each element to (the minimum value) + (the number of distinct values smaller than element).

Python- How to fix failed testcase on a has repeat function?

I've built a function that checks for repeats of a specific number in a list named xs. V is the number to check for repeats of. It needs to return True if there are more than one occurrences of the number and if there are none, it needs to return False.
I'm failing one test case which is input xs=[1,2,1] v=1, this function needs to return True, but my code is making it False. Can you see where I went wrong?
Here is my current code:
def has_repeat(xs, v):
count=0
for num in range(len(xs)):
if num == v:
count+=1
if count>1:
return True
else:
return False
You're actually iterating over the range of the length of the list, not the items in the list.
The range function returns a list of numbers from 0 (by default) to the number you provide, in this case 3 (not inclusive). See Python documentation.
As an example if you try:
l = [1, 2, 3]
print(range(len(l)))
It will print out [0, 1, 2]
What you should do is instead of
for num in range(len(xs))
do
for num in xs:
You can try it out on PyFiddle here
As an added tasty bonus, you could change this to use the .count method on your list of items to check how many occurrences of that number are in the list, removing the need to iterate the list at all, like so:
count = xs.count(v)

How I add values in a list I am using as the parameter for a function?

I am trying to understand these instructions.
Set up a new function in your main program file named “summer” that takes a list as a parameter and returns a value we will determine in the next steps.
In the “summer” function, set up a loop that uses a counter variable named “n” that will take on the values 0, 2, 4, 6, 8, 10, 12.
Each time through the loop, you are to call your “powerval” function from the “mymath” module passing as parameters item “n” and “n+1” from the list of data passed into “summer”. Add up all these values and return the final result to the caller.
So far I have:
def summer(list):
for n in range(0,13,2):
value=powerval(n,n+1)
After that I am lost. How do i perform step 3?
You add them up:
from mymath import powerval
def summer(somelist):
sum = 0
for n in range(0, 13, 2):
sum += powerval(somelist[n], somelist[n + 1])
return sum
So the return value of powerval() is added to the total sum so far, which was started at 0. You do need to pass in the somelist[n] and somelist[n + 1] values, not the indices themselves.
You need to add them up:
from mymath import powerval
def summer(lst):
total = 0
for n in range(0, 13, 2):
total += powerval(lst[n], lst[n + 1])
return total
I'm not sure where you use lst (I renamed list to lst, as list is a built-in function), so I'm guessing you're trying to get the nth and n + 1th elements from that list.
You can use the sum method to accomplish this in a very fashionable way :)
def summer(myList):
return sum(powerval(myList[n], myList[n+1]) for n in range(0, 13, 2))
This is also the fastest way.
PS: It's not a good idea to name you list "list", bacause that's a reserved name in python. That's why I have renamed it to myList in the example above.

Resources