codecademy Practice Makes Perfect digit_sum - python

The purpose is Write a function called digit_sum that takes a positive integer n as input and returns the sum of all that number's digits.
For example: digit_sum(1234) should return 10 which is 1 + 2 + 3 + 4.
(Assume that the number you are given will always be positive.)
https://www.codecademy.com/zh/courses/python-intermediate-en-rCQKw/0/4?curriculum_id=4f89dab3d788890003000096#
Your function fails on digit_sum(1000). It returns 12 when it should return 1.
If I put the dig=[] upper on the def digit_sum, the course occurred alarm that "digit_sum(1000) result is 12 instead of 1" , but I ran this program on my local notepad+powershell, it ok , the result is right.
after that I put the dig=[] into the first line of function , then it worked normally .
I didn't get 2 points....
What's the difference between "dig=[]" inside/outside the function
if the "dig=[]" outside the function is wrong , why I can ran it successfully on my local....?
Thanks for guys to help me......
dig=[]
def digit_sum(n):
u=str(n)
for i in u:
dig.append(i)
s=0
for number in dig:
int(number)
s=s+int(number)
return s

So the difference between inside/outside is locality. When you put dig outside, you create a global list. From there, you're constantly appending to that- the list is never cleared! So if I run digit_sum(1234), I properly get 10. If I immediately thereafter run digit_sum(1000), dig==['1','2','3','4','1','0','0','0'] which will then add all those and mess up.
If you do dig = [] inside the function, it creates a new, local list - it isn't being changed each time, it's a new empty list for each rotation.
The reason you're getting it correctly sometimes is because the function has side effects, so order of calling and history of calling matters. Try to avoid side effects of functions- either don't alter a list, or copy the list>alter that copy>return the copy if you want to assign the new list (or just work with the new list.)

def digit_sum(n):
n = str(n)
total = 0
for i in n:
total += int(i)
return total

Something like :
def digit_sum(n):
dig=0 # this is the result os the sum
number=str(n) #transform the number into string so we can iterate
for i in range(len(number)):
dig=dig+int(number[i]) #transform the char to int
return dig #return the sum
I take the number (eg 123) and I transform it to a string so I can get the length of the string (the number of digit). Then I simply add them (after transforming them to integers) and return the result
dig=[] means you declare an array variable which is not what you want here. If it is declared in the function it means that when the function ends, the variable "disappeared", you won't be able to call it back. It'll only exist IN the function. If it is before the function, the variable exists to the end of your program.
Your aptenpt isn't correct. You want to populate your array with the number THEN sum them. In fact when you assign a number to your array dig you are summing then. For exemple 123 will sum : 1 then 1+2 then 1+2+3

The previous answer is all right.
Just to focuse your attention so that you could avoid mistakes in the future:
When you write:
u=str(n)
for i in u:
dig.append(i)
you don't append the digits of the number to the dig. Instead you add digits 0, 1 ,2 ,3 .. so on. Exactly them however the number may be. Because the For Loop iterates from the beginning to the end of a string, a list etc. and the variable after the word For is just a counter - starting from 0 and ending at the end of the object.
Tha is why the answer of Hearner is right:
the number[i] 's are summed not the i's.
for i in range(len(number)):
dig=dig+int(number[i])

Related

how to reverse string using lists python

I found this piece of code from a related question about reversing strings in python, but can someone please interpret it in plain English? Please note that I am still new to python and only learnt how to use while loops and functions yesterday :/ so I cant really put this into words myself cause my understanding isn't quite there yet.
anyways here is the code:
def reverse_string(string):
new_strings = []
index = len(string)
while index:
index -= 1
new_strings.append(string[index])
return ''.join(new_strings)
print(reverse_string('hello'))
Surely by knowing what it does, you can figure the code. In the while loop, the index value starts from the end of the string and counts down to 0. In each step, it adds that character (again, starting from the end) to the end of the list it is building. Finally, it combines the list into a string.
So, given 'abcd', the list gets built:
'abcd' #3 -> ['d']
'abcd' #2 -> ['d','c']
'abcd' #1 -> ['d','c','b']
'abcd' #0 -> ['d','c','b','a']
Well basically, the get the length of the string with the len method. Which will return you an integer value representing how long that string is.
They then use the length of this string and effectively iterate down to zero in a while loop. Using the -= operator.
Each iteration (meaning each time around the loop) it will take away from length until it reaches zero.
So lets use hello as an example input and go through this together.
reverse_string('hello') is how we would call the method, done in the print statement of your code.
We then enter the function and perform these steps:
We create a new empty array called new_strings.
We find the length of the initial string hello which returns us 5. Meaning that now index is equal to 5.
We create a while loop that keeps on going until index is no more using while(index): - a while loop like this treats a 0 value as falsy and will terminate upon reaching this. Therefore when index is 0 the loop will stop.
The first line of this loop performs index -= 1 which is the same as writing index = index - 1 so the very first loop through we get index = 5 - 1 and then now index is equal to 4.
Because Python then lets us access the character of a string using string[index] (and because this works from 0 -> n) performing hello[4] will in fact give us the character o.
We also append this character to the array new_strings meaning that as we go through the iterations to reach zero it will add each character backwards to this array giving us ['o', 'l', 'l', 'e', 'h']
Since index is now zero we leave the loop and perform a join operation on the array to yet again create a string. The command ''.join(new_strings) means that we wish to join the array we previously had without a separator. If we had done '#'.join(new_strings) we instead would have gotten o#l#l#e#h instead of olleh.
I hope this answer gives you some clarity.
Sure, It is very simple program. You should reffer string methods and string indexing in python to get clear idea. Let me explain this in deatial.
print(reverse_string('hello'))//The print function is calling another function
reverse_string and passing argument"hello".
def reverse_string(string):// The argument "hello" is stored in the variable
string in reverse_string function.
**new_strings = []** // created a new empty list
**index = len(string)** // len function returns the length of the argument
passed to the function. len("hello")=5 and assigned
to index. index=5.
while index: // while loop exicute until the condition get false .In this
example when index =0.in string the indexing start from 0 .For
example.
string[0]=h,string[1]=e,string[2]=l,string[3]=l,string[4]=o.
**index -= 1** //Note the last letter 'o' is in string[4] and the len
function returned 5 so we need to decrement index variable
to 4 so that it will pointing to string[4]=o
new_strings.append(string[index]) // append string[4] that is o and so on ...
return ''.join(new_strings)

Finding maximum possible count of elements in list whom all sharing at least one same digit

There is a problem where array containing numbers is given, the statement is to find the maximum length of a sub-sequence formed from the given array such that all the elements in that sub-sequence share at least one common digit.
Now whats the catch? Well, I intended to use a dictionary b to store key as every digit and value as count so far while traversing the given array, digit by digit. I thought the maximum number in values of dictionary i.e., bigger count of a digit would be the problems answer, given that we still have a glitch that we should not count a same digit that present in ONE element of array more than one time. To overcome that glitch, I used set c.
The code function for this along with driver function written below for convinience.
def solve (a):
b={}
answer=1
for i in a:
j=i
c=set()
c.clear()
while(j):
last_digit=i%10
if(last_digit not in b and last_digit not in c):
b[last_digit]=1
c.add(last_digit)
elif(last_digit in b and last_digit not in c):
b[last_digit]+=1
c.add(last_digit)
answer=max(answer,b[last_digit])
j//=10
return answer
a=list(map(int,input().strip().split()))
print(solve(a))
There are lot test cases concerned for this code to be correct.. One of them is input is 12 11 3 4 5, the output that code gave is 1 and expected output is 2. What gives?
You have good ideas. But your code would be easier if you use the Counter object from the collections module. It is designed to do just what you are trying to do: count the number of occurrences of an item in an iterable.
This code uses a generator expression to look at each value in the list alist, uses the built-in str() function to convert that integer to a string of digits, then uses the set() built-in function to convert that to a set. As you said, this removes the duplicate digits since you want to count each digit only once per item. The Counter object then looks at these digits and counts their occurrences. The code then uses Counter's most_common method to choose the digit that occurs most (the (1) parameter returns only the single most popular digit in a list, and the 0 index takes that digit and its count out of the list) then takes the count of that digit (that's the 1 index). That count is then returned to the caller.
If you are not familiar with Counter or with generator expressions, you could do the counting yourself and use regular for loops. But this code is short and fairly clear to anyone who knows the Counter object. You could use the line in the comment to replace the following four lines, if you want brief code, but I expanded out the code to make it more clear.
from collections import Counter
def solve(alist):
digitscount = Counter(digit for val in alist for digit in set(str(abs(val))))
# return digitscount.most_common(1)[0][1]
most_common_list = digitscount.most_common(1)
most_common_item = most_common_list[0]
most_common_count = most_common_item[1]
return most_common_count
alist = list(map(int, input().strip().split()))
print(solve(alist))
For your example input 12 11 3 4 5, this prints the correct answer 2. Note that my code will give an error if the input is empty or contains a non-integer. This version of my code takes the absolute value of the list values, which prevents a minus (or negative) sign from being counted as a digit.
Here's my own implementation of this:
def solve(list_of_numbers):
counts = {str(i):0 for i in range(10)} # make a dict of placeholders 0 through 9
longest_sequence = 0 # store the length of the longest sequence so far
for num in list_of_numbers: # iterate through our list of numbers
num_str = str(num) # convert number to a string (this makes "is digit present?" easier)
for digit, ct in counts.items(): # evaluate whether each digit is present
if digit in num_str: # if the digit is present in this number...
counts[digit] += 1 # ...then increment the running count of this digit
else: # otherwise, we've broken the sequence...
counts[digit] = 0 # ...so we reset the running count to 0.
if ct > longest_sequence: # check if we've found a new longest sequence...
longest_sequence = ct # ...and if so, replace the current longest sequence
return longest_sequence[1] # finally, return the digit that had the longest running sequence.
It uses a dict to store the running counts of each digit's consecutive occurrences - for every number, the count is incremented if the digit is present, and reset to 0 if it isn't. The longest sequence's length so far is saved in its own variable for storage.
There are a few details that your implementation, I think, is overlooking:
Your code might be returning the digit that appears the most, rather than the greatest number of appearances. I'm not sure, because your code is kind of hard for me to parse, and you only gave the one test example.
Try to stay away from using single-letter variable names, if you can. Notice how much more clear my code above is, since I've used full names (and, at worst, clear abbreviations like ct for "count"). This makes it much easier to debug your own code.
I see what you're doing to find the digits that are present in the number, but that's a bit more verbose than the situation requires. A simpler solution, which I used, was to simply cast the number into a string and use each individual digit's character instead of its value. In your implementation, you could do something like this: c = set(int(digit) for digit in str(j))
You don't seem to have anything in your code that detects when a digit is no longer present, which could lead to an incorrect result.
I'm having trouble understanding the original problem, but I think what you need to do is cast each item as a string if it is an int and then split out each digit.
digits = {}
for item in thelist:
digit[item] = []
if len(item) > 1:
for digit in str(item):
digits[item].append(int(digit))
if your test case is 12 11 3 4 5 then this would produce a dictionary of {12 : [1,2], 11 : [1,1], etc}

Trying to find float variables in a list with recursion

I'm trying to write a program that goes through a list using recursion that counts how many float variables are in the list.
def recFloatCount(lst):
string = ''
if len(lst) <= 0:
return
else:
if type(lst[0]) == float:
string = string + str(lst[0])
recFloatCount(lst[1:])
print(len(string))
The way this is supposed to work is that the program will go though the list, add each float to string, then print the length of string. However, when I run the program using
recFloatCount([1, 2.0, 3])
it returns
0
3
0
How can I get this so it just prints 1?
This task is quite a bad place to use recursion. But lets assume you really need to
variable string being created "locally" for every function run. So, its empty while running code for 1 and 3. If you need to count floats, string is bad container. You should use integer and pass it down to next calls, so function should accept list and counter state.

The point of use of return statement

I'm curious of what's the point of using return statement.
def give_me_five():
five = 5
return five
number = give_me_five()
print("Here's what I got from give_me_five():", number)
Above code shows the following result.
Here's what I got from give_me_five(): 5
As you can see, when you can just type 5 in print("Here's what I got from give_me_five():", 5) like this, what's exactly the point of using return statement and why does it need to even make a function to set a value 5?
Why you need return
Try removing return. It then prints
Here's what I got from give_me_five(): None
If you do not return 5, you have no way to recover it outside your function.
That is why you need return. But then...
Why you need functions
In your example, your function always returns the same value, so it is not needed, but suppose you have a more complex function that returns based on an input.
def give_me_more(n)
return n + 1
This function does not always return the same value, so it is a bit more useful. But then you should ask: wait, can't I just replace that function by n + 1 in my code?
Can't we do without function?
Well yes, but keep in mind that functions can be way more complex than the above examples.
def get_factors(n):
factors = []
for i in range(int(math.sqrt(n))):
if n % i == 0:
factors.append(i)
factors.append(n / i)
return sorted(factors)
Do you want to insert this code in your script everytime you want to get the factors of a number? Of course not, and to be able to reuse code you need to write functions. Which in turn requires return.

trying to calculate and print the mean and its returning as a <function at> rather than a number? PYTHON

I have my program in python and I have used an external file with numbers in, I created a list for the numbers to be stored in and then I need to find the mean, standard deviation and the length of the list from this, at the moment my program looks like this:
data = open( "gauss.dat", "r" )
numbers=[]
for line in data:
numbers.append(line)
sorted(numbers)
def length(numbers):
length = len(numbers)
return length
def mean(numbers):
sum = 0
for element in numbers:
sum += element
mean = sum/length
return (mean)
def main():
global history
print (length)
print('The smallest number is ' + numbers[0])
print ('The largest number is ' + numbers[-1])
print(mean)
return True
if __name__ == "__main__":
main()
When I run the program
It doesn't sort the numbers correctly? I am new to python so I don't know if there is an obvious error
It prints out the mean and length as < function length at 0x039475B0 >, < function mean at 0x03947630 >. I have no idea how to change this into a number?
Hope you can help.
regarding 1)
A powerfull tool: the interactive shell combined with the help-command:
>>> help(sorted)
Help on built-in function sorted in module __builtin__:
sorted(...)
sorted(iterable, cmp=None, key=None, reverse=False) --> new sorted list
So we need either
numbers = sorted(numbers)
or
numbers.sort()
(see help(numbers.sort) for details)
regarding 2)
as stated by mgilson: you have to invoke the function:
print(mean(numbers))
regarding comment
with
for line in data:
numbers.append(line)
you read the file line-by-line as a string. But to do some calculations, you need a numeric type. One way to do this would be:
for line in data:
numbers.append(float(line))
This converts the text in line into a floating type. Leading or trailing spaces are cropped (at least in my python-interpreter) but you may run into trouble with empty or erroneous lines.
You need to call the function length and/or mean :
print(length(numbers))
print(mean(numbers))
In python, functions are objects themselves. So they have a representation that gets printed. You can assign them to different names in your current namespace, pass them to other functions, etc. e.g.
MeAn = mean # This is a violation of PEP 8!
print(MeAn(numbers)) #same as `print(mean(numbers))`
In other words, when you tell python:
print(mean)
It prints information about the function object mean. It doesn't run the function however, so there is no way to get at it's return value (After all, how should it know what to use as input arguments?)
sorted returns sorted version of iterable, but doesn't change it, you need one of those:
numbers = sorted(numbers)
or:
numbers.sort()
About functions, you need to call them, with necessary arguments - eg:
mean = sum/length(numbers)
You have this bug in several places in your code.

Categories

Resources