Can someone explain to me why when I remove 'str' from 7 line of code "myset.add(str(i))", do I get the same numbers every time I hit run and get random numbers with 'str' included?
def RandomFunction(x, y):
myset = set()
mylist = []
listofnumbers = []
for i in range(x, y):
myset.add(str(i))
for x in myset:
mylist.append(int(x))
if len(mylist) <= 5:
print('In order to generate 5 numbers, the range of input needs to be higher')
else:
for y in mylist:
listofnumbers.append(y)
if len(listofnumbers) >= 5:
print(listofnumbers)
break
RandomFunction(10, 20)
Set keeps the elements in hash table, it uses default python's hash() function. Its implementation for numeric types looks like this:
def hash(number):
return number % (2 ** 61 - 1)
So, if the numbers aren't huge, hash value of an integer will be equal to the same integer. Because of this integers in python's set will be kept in ascending order (for also reads hash table in ascending order).
But string is a sequense of unicode characters with \0 at the end and python has another implementation of hash() for strings, so it won't work the same way for them.
Related
I have the following prompt:
We want you to calculate the sum of squares of given integers, excluding any negatives.
The first line of the input will be an integer N (1 <= N <= 100), indicating the number of test cases to follow.
Each of the test cases will consist of a line with an integer X (0 < X <= 100), followed by another line consisting of X number of space-separated integers Yn (-100 <= Yn <= 100).
For each test case, calculate the sum of squares of the integers, excluding any negatives, and print the calculated sum in the output.
Note: There should be no output until all the input has been received.
Note 2: Do not put blank lines between test cases solutions.
Note 3: Take input from standard input, and output to standard output.
Specific Rules for Python Solution:
Your source code must be a single file, containing at least a main function
Do not use any for loop, while loop, or any list / set / dictionary comprehension
I have written my square_sum function as:
def square_sum(arr):
if not arr:
return 0
value = arr[0]
if value < 0:
value = 0
return value**2 + square_sum(arr[1:])
square_sum([9, 6, -53, 32, 16])
However, I cannot figure out how to run the multiline test cases on my function and display the result in the aforementioned format. Interestingly, there can be any number of test cases so how do I add the capability to accommodate them? I would like some guidance in this part, thank you.
Assuming that this assignment is to see how to replace all iteration with recursion, and withholding all judgement on the wisdom of doing so, here is a sample solution.
You have already implemented the inner loop. My suggestion would be to add the parsing to that loop, since otherwise you have to either use map or replace it with another recursion.
def square_sum(lst):
if not lst:
return 0
value = int(lst[0])
if value < 0:
value = 0
return value**2 + square_sum(lst[1:])
The outer loop will need to read two lines: the first (discarded) line will contain the number of elements. The second line will contain the strings that you will pass to square_sum. To control the depth of your recursion, use the first line of the input, which tells you how many samples there will be:
def run(n):
count = int(input())
print(square_sum(input().split()))
if n > 1:
run(n - 1)
def main()
n = int(input())
run(n)
Your question asks for a main function. If you need to run it in your module, go ahead and do that:
main()
I am trying to convert a list which previously has some integer values, strings and floats all to integers, however am running into some issues during the conversion. Here is what I have done:
class NumbersIterable:
def __init__(self, numbers):
self.numbers = numbers
print(self.numbers)
def runConversion(self):
return NumbersIterator.convertNumbers(self.numbers)
class NumbersIterator:
def convertNumbers(numbers):
print('in numbers')
for i in numbers:
int(i)
print(numbers)
return numbers
niterable = NumbersIterable(["1", 2.0, "4",5,6.1,"7",8,9.2])
niterable = niterable.runConversion()
sum = 0
for i in niterable:
print(i)
sum += i
print("sum =", sum)
I have some print statements along the way to verify the process, however after it runs through the for loop in NumbersIterator, the print statement shows the values in the list are not converted to integers and as such a error is thrown when running the for loop further down.
Is there anything I might be missing/spelling incorrectly here?
Thanks
You can use a simple list comprehension to convert all numbers:
def convertNumbers(numbers):
return [int(i) for i in numbers]
In your code, int(i) converts i into an integer, and then throws it away. You need to store the converted value in a list. One way of doing so, among many others, is initializing an empty list and then appending int(i):
class NumbersIterator:
def convertNumbers(numbers):
print('in numbers')
output = []
for i in numbers:
output.append(int(i))
print(numbers)
return output
Alternatively, list comprehension (as proposed by Pedro Maia) or using map would be more concise.
I'm having trouble with this code below.
My task is to create a function, that among the given numbers finds one that is different in evenness, and returns a position of that number. The numbers are given as a string. So far I have managed to convert the string into an integer list, then using for loop to iterate through each number.
The problem I'm encountering is that I've managed to return only the position of an odd number among the even numbers, and I can't continue on with the code for vice versa action, because it only returns the position of the odd number.
Here is the code:
def iq_test(numbers):
# Splitting the "numbers" string
num_split = numbers.split()
# converting the splitted strings into int
num_map = map(int, num_split)
# converting the object into list
list_num = list(num_map)
for n in list_num:
if not n%2 == 0:
return list_num.index(n) + 1
Your problem is, that you are assuming, that you are searching for the first even number. What you have to do, is to first decide, what you are searching for. You could for example simply first count the number of even numbers. If it is one, then you are looking for an even number, otherwise, you are looking for an odd. As you don't care for the actual numbers, I would map all of them to their value mod 2 as so:
num_map = list(map(lambda x: int(x) % 2, num_split))
Then, the rest is simple. For example like this:
def iq_test(numbers):
# Splitting the "numbers" string
num_split = numbers.split()
# converting the splitted strings into even (0) or odd (1)
num_map = list(map(lambda x: int(x) % 2, num_split))
# return the correct position based on if even or odd is in search
evens = num_map.count(0)
if evens == 1:
return num_map.index(0) + 1
else:
return num_map.index(1) + 1
I came up with a similar and a little bit shorter solution
def iq_test(numbers):
# first check what im looking for "even" or "odd", map a lambda function that basically does it for me, using the numbers argument as a list type and afterwards cast it into a list so i can iterate later on
num_map = list(map(lambda x: 'e' if int(x) % 2 == 0 else 'o', numbers.split()))
# search for even numbers numbers
if num_map.count('e') == 1:
return num_map.index('e') + 1
# search for odd numbers numbers
return num_map.index('o') + 1
def iq_test(numbers):
# Splitting the "numbers" string
num_split = numbers.split()
# converting the splitted strings into int
num_map = map(int, num_split)
# converting the object into list
list_num = list(num_map)
for n in list_num:
if not n%2 == 0:
return list_num.index(n) + 1
I was trying to create a list comprehension from a function that I had and I came across an unexpected behavior. Just for a better understanding, my function gets an integer and checks which of its digits divides the integer exactly:
# Full function
divs = list()
for i in str(number):
digit = int(i)
if digit > 0 and number % digit == 0:
divs.append(digit)
return len(divs)
# List comprehension
return len([x for x in str(number) if x > 0 and number % int(x) == 0])
The problem is that, if I give a 1012 as an input, the full function returns 3, which is the expected result. The list comprehension returns a ZeroDivisionError: integer division or modulo by zero instead. I understand that it is because of this condition:
if x > 0 and number % int(x) == 0
In the full function, the multiple condition is handled from the left to the right, so it is fine. In the list comprehension, I do not really know, but I was guessing that it was not handled in the same way.
Until I tried with a simpler function:
# Full function
positives = list()
for i in numbers:
if i > 0 and 20 % i ==0:
positives.append(i)
return positives
# List comprehension
return [i for i in numbers if i > 0 and 20 % i == 0]
Both of them worked. So I am thinking that maybe it has something to do with the number % int(x)? This is just curiosity on how this really works? Any ideas?
The list comprehension is different, because you compare x > 0 without converting x to int. In Py2, mismatched types will compare in an arbitrary and stupid but consistent way, which in this case sees all strs (the type of x) as greater than all int (the type of 0) meaning that the x > 0 test is always True and the second test always executes (see Footnote below for details of this nonsense). Change the list comprehension to:
[x for x in str(number) if int(x) > 0 and number % int(x) == 0]
and it will work.
Note that you could simplify a bit further (and limit redundant work and memory consumption) by importing a Py3 version of map at the top of your code (from future_builtins import map), and using a generator expression with sum, instead of a list comprehension with len:
return sum(1 for i in map(int, str(number)) if i > 0 and number % i == 0)
That only calls int once per digit, and constructs no intermediate list.
Footnote: 0 is a numeric type, and all numeric types are "smaller" than everything except None, so a str is always greater than 0. In non-numeric cases, it would be comparing the string type names, so dict < frozenset < list < set < str < tuple, except oops, frozenset and set compare "naturally" to each other, so you can have non-transitive relationships; frozenset() < [] is true, [] < set() is true, but frozenset() < set() is false, because the type specific comparator gets invoked in the final version. Like I said, arbitrary and confusing; it was removed from Python 3 for a reason.
You should say int(x) > 0 in the list comprehension
So I'm trying to work to create a program which can take two inputs such as
encrypt('12345','12')
and it will return
'33557'
where the code ('12345') and been incremented by the key ('12'), working from right to left.
I have already created one which will work for when the code and key are both 8 long, but I cannot work out how to do this should the code be allowed to be any size, possibly with nested for statments?
Here is the one i did early so you can see better what i am trying to do
def code_block(char,charBlock):
if len(char) == 8 and len(charBlock) == 8: #Check to make sure both are 8 didgets.
c = char
cB = charBlock
line = ""
for i in range(0,8):
getDidget = code_char2(front(c),front(cB))
c = last(c)
cB = str(last(cB))
line =line + getDidget
print(line)
else:
print("Make sure two inputs are 8 didgets long")
def front(word):
return word[:+1]
def last(word):
return word[+1:]
Some code tested on Python 3.2:
from decimal import Decimal
import itertools
def encrypt(numbers_as_text, code):
key = itertools.cycle(code[::-1])
num = Decimal(numbers_as_text)
power = 1
for _ in numbers_as_text:
num += power * int(next(key))
power *= Decimal(10)
return num
if __name__ == "__main__":
print(encrypt('12345','12'))
Some explanation:
code[::-1] is a cool way to reverse a string. Stolen from here
itertools.cycle endlessly repeats your key. So the variable key now contains a generator which yields 2, 1, 2, 1, 2, 1, etc
Decimal is a datatype which can handle arbitrary precision numbers. Actually Python 3's integer numbers would be sufficient because they can handle integer numbers with arbitrary number of digits. Calling the type name as a function Decimal(), calls the constructor of the type and as such creates a new object of that type. The Decimal() constructor can handle one argument which is then converted into a Decimal object. In the example, the numbers_as_text string and the integer 10 are both converted into the type Decimal with its constructor.
power is a variable that starts with 1 is multiplied by 10 for every digit that we have worked on (counting from the right). It's basically a pointer to where we need to modify num in the current loop iteration
The for loop header ensures we're doing one iteration for each digit in the given input text. We could also use something like for index in range(len(numbers_as_text)) but that's unnecessarily complex
Of course if you want to encode text, this approach does not work. But since that wasn't in your question's spec, this is a function focused on dealing with integers.