Counting a specific string in the list in Python - python

I want to count 'fizz' in the list and I wrote below code and it doesn't worked. Tell me why and provide a solution. I was doing this tutorial and I have to write code as their instruction but I am unable to do what they said or maybe I misunderstood them.
count = 0
def fizz_count(x):
for string in x:
if string == 'fizz':
count = count + 1
else:
count = count
return count
If you want to check if your answer is correct then you have to check it by interpreting it here. Note that I am not calling my own function. Instead, their is an built in feature in Codecademy tutorial it checks function by calling function with some argument.

You need to have the count variable inside for loop, and you dont require an else condition
def fizz_count(x):
count=0
for string in x:
if string == 'fizz':
count = count + 1
return count
You can also write your function as
def fizz_count(x):
return x.count('fizz')

Have a look at this below code. I made some correction in it. There were some syntactical error and some indentation errors which I fixed it. Have a look at it:
def fizz_count(x):
count = 0
for string in x:
if string == 'fizz':
count = count + 1
else:
count = count
return count
str1 = fizz_count(['fizzers','fizzerlss','fizz','fizz'])
print str1

Edit: Same with more explanation due to down votes
Considering your approach with a global variable count (global, because it is not within the function), you would need to do two adaptions:
You need to make count available locally with the keyword global
Since you use a global variable, you do not need to return it because it is available anyway
Code:
count = 0
def fizz_count(x):
global count # make count available for writing in the local scope
for string in x:
if string == 'fizz':
count = count + 1
else:
count = count
Now actually using a global variable especially for such kind of tasks is not recommended, because it takes more time to load, you have to take care of the current state and stuff like that, so you rather'd introduce a local variable and pass it via the return statement as you did.
Put count = 0 into function
Code
# we put count = 0 into the function
def fizz_count(x):
count = 0 # right here
for string in x:
if string == 'fizz':
count = count + 1
else:
count = count
return count
Now a new count will be initialized to zero within the function.
Now there are two more things here:
the else statement
and the increment
Since the else statement is outside the loop it will be only executed if the if condition was never True during the loop. That has some use cases. But you'd put it in the loop usually. However, in your case it basically does not change anything, thats why it can be removed completely.
Well and the second point is that the increment can be written as count += 1 which is considered more readable, because it is less clumsy and the second count is merged into the +=
Therefore finally the function could be written like so
def fizz_count(x):
count = 0
for string in x:
if string == 'fizz':
count += 1
return count
Check also the reasonable solutions of the other answers

Related

recursive way to find if a string is valid

hey so i am trying to write a code that that tells me if a string is valid or not .
a valid string is a string that contains an equal number of "(" and ")" and each "(" must be closed by a ")"
for example
'((()()))' this is a valid string . this isn't ')( '
this is what i wrote so far :
def is_valid_paren(s, cnt=0):
if s == "":
return True
if "(" in s:
cnt += 1
if ")" in s:
cnt -= 1
return is_valid_paren(s[1:])
it doesn't give the correct output for
"(.(a)"
yet for
"p(()r((0)))"
it does
why does it sometimes work ?
oh one more thing this is to be solved only by recursion ( without the use of loops anywhere )
While I don't understand why you want to solve this problem with recursion (it's very unnatural in this case), here is a recursive solution:
def is_valid(s):
def _is_valid(s, idx):
if idx == len(s): return 0
if s[idx] == '(': return _is_valid(s, idx + 1) + 1
if s[idx] == ')': return _is_valid(s, idx + 1) - 1
return _is_valid(s, idx + 1)
return _is_valid(s, 0) == 0
You can pass down a count of pending apertures (i.e. number of unclosed parentheses) and check if the count goes below 0 (too many closures) as you go and if it ends back at zero at the end:
def validPar(s,count=0):
if count<0 : return False # too many closing
if not s: return count == 0 # must balance pending apertures
return validPar(s[1:],count+(-1,1)[s[0]=="("]) # pass down count +/- 1
print(validPar('((()()))')) # True
Recursion
Iteration is likely to be the best method of solving this, but recursion also works. To attack this problem recursively, we need a system of checking the count of each and if at any stage that count falls below zero, the parentheses will be invalid because there are more closing brackets than opening ones. This is where the tough section comes into play: we need some method of not only returning the count, but whether or not the past ones were valid, so we will have to return and save using variables like return count, valid and count, valid = is_valid_parentheses(s[1:]). The next thing we need is some over-arching function which looks at the end results and says: "is the count equal to zero, and were the parentheses valid to begin with". From there, it needs to return the result.

python range step size not possible using enumerate

Still at the early stages of learning Python. I've written a small piece of code using the range() function:
str = "horizon"
# method 2
def printStrInt():
#print("length of str ",len(str))
for i in range(0,len(str)-1,2):
#print("i=",i)
print("Method 2",myStr[i])
# Calling method
print ("Calling Method")
printStrInt()
After this I learnt that there is a new concept called "enumerator", so I tried to rewrite the above as:
#method 3
str = "horizon"
def printStrIntervals():
for count,stringy in enumerate(str):
print("External to if call count= ",count)
if (count %2 == 0):
print("inside if, count= ",count)
count += 2
print("inside if + increment, count= ",count)
print(stringy)
#calling method
print ("Calling Method 3")
printStrIntervals()
The trouble is with method 3. The "count += 2" call does increment the variable "count" by two, but when the "for" loop iterates, count hasn't actually jumped up by two. Can you please advise what is the right way to make enumerate work the same as Range?
You're violating the use model of enumerate: it is for smooth iteration over a data object, not for jumping items. It's an extension of for stringy in my_str, not for count in range(len(my_str)).
Also, any time you alter the loop index within the loop, you're violating the for assumptions, and you are at the mercy of language semantics. You tried to alter those semantics, and escaped with a mere "you can't do that", rather than a crash.
If you want to make an intermittent skip, then simply build your own while. This is the proper use: for is applicable when you know how many times you will execute the loop at the time of loop entry.
count = 0
while count < len(my_str):
stringy = my_str[count]
...
count += 1
It is not considered good practice to modify the for-loop variables (here: count and stringy). Consider using the code below instead:
str = "horizon"
def printStrIntervals_mod():
for count,stringy in enumerate(str):
print("External to if call count= ",count)
if (count %2 == 0):
print("inside if, count= ",count)
print(stringy)
#calling function
print("Calling Method 3")
printStrIntervals_mod()

Reset counter to zero if different day - Python

New to python, so I have this setup where I file gets created, and I have to add an extension number. The first file will have an extension number of 1 since being the first. A second file gets created and the extension number will increment, so it will be 2. So each files gets created, the extension number will increment.
Now, if it's a different day then that extension number will reset to 1, and it will increment if new files are created. So each day, the extension number needs to be reset to 1
def get_counter(date):
counter = 1
now = datetime.datetime.utcnow().strftime('%Y-%m-%d')
if date != now:
now = date
counter = 1
return counter
counter += 1
return counter
I have set up this function but it will not work because the now and counter variable will get overwritten. So will need these variables somewhere else. Just wondering if there is a work around this process or is there a python library that can handle this type of situation. Your suggestions will be appreciated!
You could assign the counter outside of that function and send it as a parameter, that way you don't overwrite it every single time you call your function, like so:
counter = 1
for file_to_be_writen in file_collection:
counter = get_counter(date, counter)
and leave your function like this:
def get_counter(date, counter):
now = datetime.datetime.utcnow().strftime('%Y-%m-%d')
if date == now:
counter += 1
return counter
return counter
When you need to preserve state across function calls that is a hint that you need a custom object. You could use global variables as well but encapsulating the state inside an object is usually better.
Here I implement a class Counter that takes care of everything. It has a __next__ method that returns the next number so the calling code only needs to call next(counter). It also has an __iter__ method so it can be used in for loops.
You need to provide a function to get the current (date_getter) time when creating an instance. Besides making the code more testable this allows you to decide if you want to use utc time, local time, the first day of the week so the counter resets each week, etc.
import datetime
class TimeArrowReversedError(Exception):
pass
class Counter:
def __init__(self, date_getter):
self._date_getter = date_getter
self._current_date = date_getter()
self._current_value = 0
def _check_date(self):
current_date = self._date_getter()
if self._current_date > current_date:
message = 'Time arrow got reversed. Abandon all hope.'
raise TimeArrowReversedError(message)
if self._current_date < current_date:
self._current_date = current_date
self._current_value = 0
def __next__(self):
self._check_date()
self._current_value += 1
return self._current_value
def __iter__(self):
return self
This is the code I used to test it. Note that I am using as date_getter a function that actually returns whatever date I want. I do not want to wait until 23:59 to run the test. Instead I tell the function which date to return (including going backwards in time) and see how the counter behaves.
current_date = datetime.date(year=2018, month=5, day=9)
get_current_date = lambda: current_date
counter = Counter(get_current_date)
n = next(counter)
assert n == 1
n = next(counter)
assert n == 2
for expected, result in zip([3, 4], counter):
assert expected == result
current_date = current_date + datetime.timedelta(days=1)
n = next(counter)
assert n == 1
n = next(counter)
assert n == 2
current_date = current_date - datetime.timedelta(days=2)
try:
n = next(counter)
except TimeArrowReversedError:
pass
else:
raise AssertionError('"TimeArrowReversedError" expected.')
Here is a more realistic way in which yo could use this class:
def create_counter():
return Counter(datetime.datetime.utcnow().date)
counter = create_counter()
Print the first couple of numbers:
print(next(counter))
print(next(counter))
Output:
1
2
Using a loop to add numbers to names in a list:
names = ['foo', 'bar']
for name, n in zip(names, counter):
print('{}_{}'.format(name, n))
Output:
foo_3
bar_4
Now I realize that Counter is a really bad choice because there is already a completely unrelated Counter class in the standard library. But I cannot think of a better name right now so I will leave it as is.

Keeping count in a recursive function? [Jython]

I'm trying to count the number of times the letter 'x' appears in a string using a recursive function. My function currently does this, however I wish to have only one parameter (the string). I am having difficulty creating a counter that is not overwritten when the function is iterated in the return line.
To illustrate what I mean:
def xCounter(string): <br>
**counter = 0** (This resets the counter to 0 with each iteration) <br>
if len(string) == 0:
return counter
elif string[0] == 'x':
counter = counter + 1
elif string[0] != 'x':
return xCounter(string[1:],counter)
return xCounter(string[1:],counter)
xCounter("gfljkgfxlkjsfxxljsx")
0
The only way I have it working so far is defining counter as a parameter:
def xCounter(string, counter): <br>
if len(string) == 0: <br>
return counter <br>
elif string[0] == 'x': <br>
counter = counter + 1 <br>
elif string[0] != 'x': <br>
return xCounter(string[1:],counter) <br>
return xCounter(string[1:],counter) <br>
xCounter("werixiuewrxiewx",0)
3
Can anyone please provide me some insight on how to keep count in this function without overwriting the count or defining count as a parameter?
I assume you're doing this for exercise in recursion, not for actual solution, right? The right way to do it in python would be
count = "gfljkgfxlkjsfxxljsx".count('x')
print count
However, you are correct in that your code resets the counter with each iteration, it's supposed to.
There are ways (like global variables) to keep track of the counter without using it as a parameter, but that's BAD BAD BAD. The extra parameter is the way to do it right.
Try this:
def xCounter(string):
if len(string) == 0: return 0
return (string[0]=='x') + xCounter(string[1:])
... if you reach the end of a string, you return 0, otherwise you return 0 or 1 (depending whether string[0] is 'x') plus the function value for the rest of the string... you sum all these numbers in the end and get your answer!
Of course, that's not how it's done, but it's a good practice in recursive functions.
You can even do it shorter, like a lambda:
f=lambda s:len(s) and (s[0]=='x') + f(s[1:]) or 0
Return the recursive call, plus 1 if the character is present. The counter in this case would either be a 0 or a 1; instead of a running total.
You could set a Boolean variable to whether or not the current character is an 'x', then you can change the last line to something like:
return xCounter[1:] +
(if isX then 0 else 1)
The end result will be a chain of addition expressions, where the end result (an addition "chain" of 1s and 0s) is returned.
You could also wrap the "workhorse" function in a wrapper that automatically passes in the initial parameter so the caller doesn't have to:
def xCounter(str):
return xCounterHelper(str, 0)
where xCounterHelper is your original function.
In complicated recursive functions that require more parameters, the second option is very handy. Hide the ugly multi-parameter version as a private function (if it's a class method), and expose the cleaner 1 parameter version (note that Python doesn't have private functions. This is more for languages that do).

How to count the number of letters in a string with a list of sample?

value = 'bcdjbcdscv'
value = 'bcdvfdvdfvvdfvv'
value = 'bcvfdvdfvcdjbcdscv'
def count_letters(word, char):
count = 0
for c in word:
if char == c:
count += 1
return count
How to count the number of letters in a string with a list of sample? I get nothing in my python shell when I wrote the above code in my python file.
There is a built-in method for this:
value.count('c')
functions need to be called, and the return values need to be printed to the stdout:
In [984]: value = 'bcvfdvdfvcdjbcdscv'
In [985]: count_letters(value, 'b')
Out[985]: 2
In [987]: ds=count_letters(value, 'd') #if you assign the return value to some variable, print it out:
In [988]: print ds
4
EDIT:
On calculating the length of the string, use python builtin function len:
In [1024]: s='abcdefghij'
In [1025]: len(s)
Out[1025]: 10
You'd better google it with some keywords like "python get length of a string" before you ask on SO, it's much time saving :)
EDIT2:
How to calculate the length of several strings with one function call?
use var-positional parameter *args, which accepts an arbitrary sequence of positional arguments:
In [1048]: def get_lengths(*args):
...: return [len(i) for i in args]
In [1049]: get_lengths('abcd', 'efg', '1234567')
Out[1049]: [4, 3, 7]
First you should probably look at correct indenting and only send in value. Also value is being overwritten so the last one will be the actual reference.
Second you need to call the function that you have defined.
#value = 'bcdjbcdscv'
#value = 'bcdvfdvdfvvdfvv'
value = 'bcvfdvdfvcdjbcdscv'
def count_letters(word, char):
count = 0
for c in word:
if char == c:
count += 1
return count
x = count_letters(value, 'b')
print x
# 2
This should produce the result you are looking for. You could also just call:
print value.count('b')
# 2
In python, there is a built-in method to do this. Simply type:
value = 'bcdjbcdscv'
value.count('c')

Categories