I am working with the code that would read the input of the strings and compute whether the parenthesis (using arbitrary characters for open and close) are balanced. The aim is to prompt user to input the amount of brackets as strings, so the compiler would compute their amount and type(ex. if it is '(' or ')') .
I have been given hints:
Hint1: introduce two counters initialized to zero in the beginning.
Then explore the symbols of the string in a loop. For the current
symbol increment the left counter by 1 if the symbol is '(',
otherwise, increment by 1 the `right' counter
Hint2: call a string math-like if the brackets occur like in a
mathematical formula. For instance, the strings '()', '(())()',
'(()())' are balanced, while the strings '))(())((' and '())(()'
are not.
My code now looks like this:
lefts =str(input("Please enter a left parenthesis: "))
rights =str(input("Please enter a right parenthesis: "))
#token parsing requires paying attention to the order of the parenthesis
def ptest(test): #testing with counters
lefts = 0
rights = 0
balance = 0 #additional counter that will help us determine the amount of strings and their relation to each other
for c in test:
if c == '(':
balance += 1
lefts += 1
elif c == ')':
balance -= 1
rights += 1
print ('testing "'+test+'"')
print ('lefts='+str(lefts)+' rights='+str(rights))
#if there will b a balance between the strings/parenthesis, they will possibly be balanced
if balance == 0: print 'same number of open/close, possibly balanced'
else: print 'different number of open/close, definitely not balanced'
ptest(test1)
ptest(test2)
How could I modify this in order that it would work?
But I think you partly misunderstood the task.
There can be many brackets, but no more ")" than "(" (and at the end the number of both types must be equal)
And I would think, that the input not only consists of brackets
So you should build a loop (as you did) and
test, whether the char is a bracket or not
if a bracket, so increase the matching counter (you could even have one Counter, but it is easier to understand with two of them
Check, whether the closing Counter is smaller than the opening (if not, so you could break the Loop, cause it is not mathematical)
After the end of the loop you must check, whether there were an error in the Loop or both Counters are not equal. In both cases the string is not "mathematical", otherwise it is.
I could do it in your code, but I think, you should do THIS alone. Most of These things you have already done, but it seems as you did not completly understand, what you have done and have to do.
Related
So i'm trying to solve this problem and the question goes like this
Probably, You all Know About The Famous Japanese Cartoon Character Nobita and Shizuka. Nobita Shizuka are very Good friend. However , Shizuka Love a special kind of string Called Tokushuna.
A string T is called Tokushuna if
The length of the string is greater or equal then 3 (|T| ≥ 3 )
It start and end with a charecter ‘1’ (one)
It contain (|T|-2) number of ‘0’ (zero)
here |T| = length of string T . Example , 10001 ,101,10001 is Tokushuna string But 1100 ,1111, 0000 is not.
One Day Shizuka Give a problem to nobita and promise to go date with him if he is able to solve this problem. Shizuka give A string S and told to Count number of Tokushuna string can be found from all possible the substring of string S . Nobita wants to go to date with Shizuka But You Know , he is very weak in Math and counting and always get lowest marks in Math . And In this Time Doraemon is not present to help him .So he need your help to solve the problem .
Input
First line of the input there is an integer T, the number of test cases. In each test case, you are given a binary string S consisting only 0 and 1.
Subtasks
Subtask #1 (50 points)
1 ≤ T ≤ 100
1 ≤ |S| ≤ 100
Subtask #2 (50 points)
1 ≤ T ≤ 100
1 ≤ |S| ≤ 105
Output
For each test case output a line Case X: Y where X is the case number and Y is the number of Tokushuna string can be found from all possible the substring of string S
Sample
Input
3
10001
10101
1001001001
Output
Case 1: 1
Case 2: 2
Case 3: 3
Look, in first case 10001 is itself is Tokushuna string.
In second Case 2 Substring S[1-3] 101 and S[3-6] 101 Can be found which is Tokushuna string.
What I've done so far
I've already solved the problem but the problem is it shows my code exceeds memory limit (512mb). I'm guessing it is because of the large input size. To solve that I've tried to clear the list which holds all the substring of one string after completing each operation. But this isn't helping.
My code
num = int(input())
num_list = []
for i in range(num):
i = input()
num_list.append(i)
def condition(a_list):
case = 0
case_no = 1
sub = []
for st in a_list:
sub.append([st[i:j] for i in range(len(st)) for j in range(i + 1, len(st) + 1)])
for i in sub:
for item in i:
if len(item) >= 3 and (item[0] == '1' and item[-1] == '1') and (len(item) - 2 == item.count('0')):
case += 1
print("Case {}: {}".format(case_no, case))
case = 0
case_no += 1
sub.clear()
condition(num_list)
Is there any better approach to solve the memory consumption problem?
Have you tried taking java heap dump and java thread dump? These will tell the memory leak and also the thread that is consuming memory.
Your method of creating all possible substrings won't scale very well to larger problems. If the input string is length N, the number of substrings is N * (N + 1) / 2 -- in other words, the memory needed will grow roughly like N ** 2. That said, it is a bit puzzling to me why your code would exceed 512MB if the length of the input string is always less than 105.
In any case, there is no need to store all of those substrings in memory, because a Tokushuna string cannot contain other Tokushuna strings nested within
it:
1 # Leading one.
0... # Some zeros. Cannot be or contain a Tokushuna.
1 # Trailing one. Could also be the start of the next Tokushuna.
That means a single scan over the string should be sufficient to find them all.
You could write your own algorithmic code to scan the characters and keep track
of whether it finds a Tokushuna string. But that requires some tedious
bookkeeping.
A better option is regex, which is very good at character-by-character analysis:
import sys
import re
# Usage: python foo.py 3 10001 10101 1001001001
cases = sys.argv[2:]
# Match a Tokushuna string without consuming the last '1', using a lookahead.
rgx = re.compile(r'10+(?=1)')
# Check the cases.
for i, c in enumerate(cases):
matches = list(rgx.finditer(c))
msg = 'Case {}: {}'.format(i + 1, len(matches))
print(msg)
If you do not want to use regex, my first instinct would be to start the algorithm by finding the indexes of all of the ones: indexes = [j for j, c in enumerate(case) if c == '1']. Then pair those indexes up: zip(indexes, indexes[1:]). Then iterate over the pairs, checking whether the part in the middle is all zeros.
A small note regarding your current code:
# Rather than this,
sub = []
for st in a_list:
sub.append([...]) # Incurs memory cost of the temporary list
# and a need to drill down to the inner list.
...
sub.clear() # Also requires a step that's easy to forget.
# just do this.
for st in a_list:
sub = [...]
...
I found out I can solve this problem in a better space complexity if I enter inputs one at time. However, python is defeating the purpose of my script.
Because python is outputting O(n) elements that I just gave for input.
0
2
no
See that 0 and 2 for inputs? I only need one line. And it can only have the current input for that one particular line. (not 0,2....) Otherwise, the computer is technically still using O(n) space just for the graphics card to remember what pixels to output.
I tried using os.devnull and other methods. But, the computer still used O(N) space by simply outputting none or null. Outputting space characters still use O(N) space so does every other possible character you can think of. Output must be 100% suppressed excluding the yes or no outputs.
This isn't impossible because I guarantee you that the algorithm works by hand with an auxiliary space better than O(N)
# Decision Problem: Is N in index M?
import sys
import os
M = 2
N = 2
index = -1
while True:
# We are going to enter each element from our list ONE AT A TIME.
# This will improve our space-complexity that is better than O(n)
# Be careful not to enter the elements out of order.
a = int(input(os.devnull))
index = index + 1
if a == N:
if index == M:
print('yes')
break
if index > M:
print('no')
break
if index < M:
if a == N:
print('no')
break
Question
How do I suppress output completely without losing my "yes" or "no" outputs?
I'm new to python. I've recently begun playing around with the concepts to try and expand my understanding and application. I tried a simple problem being "count the vowels in a string". I was able to solve it however, i was looking at other people's code and found this:
def vowel_count (string):
find_vowel = 0
for letter in string.lower():
if letter in "aeiou":
find_vowel += 1
return find_vowel
Can anyone break down this code line by line for me please.
I'm especially a bit disoriented with understanding the concept of starting off with find_vowel = 0 and the part where is has find_vowel +=1. I interpreted this as find_vowel being assigned a new value of 1 as it was added to the previous value of zero, but i'm not sure exactly how it is connected or counts the vowels exactly. I ran the code though and it works so I'd just like to know the finer details behind it.
Thanks in advance!
If you're asking what += means, then I can tell you that.
+= is an operator that adds to a variable. It increments a variable by any amount, and it is a very helpful shortcut.
Say you have a variable called money.
To add to money, you could do this:
money = money + 1
A shorcut to that would be:
money += 1
Hopefully this helps!
An implementation with better variable naming would be this:
def count_vowels(string):
count = 0
for letter in string.lower():
if letter in "aeiou":
count += 1
return count
The += operator increments, or adds 1 to, the count value. Every time a vowel is found, the value of count increases by 1, representing the presence of that vowel in the string.
i have a question
Write a program to check the validity of password input by users.
Following are the criteria for checking the password:
At least 1 letter between [a-z]
At least 1 number between [0-9]
At least 1 letter between [A-Z]
At least 1 character from [$##]
Minimum length of transaction password: 6
Maximum length of transaction password: 12
Your program should accept a sequence of comma separated passwords and will
check them according to the above criteria. Passwords that match the criteria are
to be printed, each separated by a comma
Example
If the following passwords are given as input to the program:
ABd1234#1,a F1#,2w3E*,2We3345
Then, the output of the program should be:
ABd1234#1
the solution is below
def check_password(word):
special_str = "$##"
accepted = []
passwords = word.split(',')
for password in passwords:
lower = 0
upper = 0
digits = 0
special = 0
for char in password:
if char.islower():
lower += 1
elif char.isupper():
upper += 1
elif char.isdigit():
digits += 1
elif special_str.find(char) != -1:
special += 1
if lower >= 1 and upper >= 1 and digits >= 1 and special >= 1 and len(password) in range(6,13):
accepted.append(password)
return accepted
i was told to also write a unit test for it
Now am new to using unit tests, so after going through some examples i tried writing a unit test as below
import unittest
import question1
class Test_PasswordChecker(unittest.TestCase):
def test_valid(self):
self.assertEquals(question1.check_password("ABd1234#1,a F1#,2w3E*,2We3345"),'ABd1234#1')
if __name__ == '__name__':
unittest.main()
The source code works well, though am having problems on whether i have made the correct unit test for it.
Need some help on how to make the best unit test
First of all your code has an issue: you are printing the result instead of returning it.
As a general principle you should always strive to decouple input-ouput to "processing". If you have functions that both compute stuff and print/request input you end up reducing their reusability and testability.
In this case the issue with your unittest is that check_password always returns None since you did not return anythign and hence it will always fail.
So first thing replace:
print(accepted)
with
return accepted
Now: you need more than one test for this function. You should try to write a test for all possible cases.
For example:
check what happens when no password satisfies the requirements?
What happens if all satisfy the requirements?
What happens if you give the empty input to the function?
For each requirement try to see what happens if you try to call the function with a password that satisfies all requirement except that one.(e.g. a password that has a lowercase letter, an uppercase letter, a symbol, a digit but whose length is 4 or 20).
Basically you should try to divide the possible input into a number of categories and check at least one input for each category.
It prints diga and digb but doesnt work with c! Any help? It's supposed to be a Denary to Binary converter but only 1-64, once i've cracked the code will increase this! Thanks so much
denaryno=int(input("Write a number from 1-64 "))
if 64%denaryno > 0:
diga=0
remaindera=(64%denaryno)
if 32/denaryno<1:
digb=1
remainderb=(denaryno%32)
else:
digb =0
if 16/remainderb<1:
digc=1
remainderc=(denaryno%16)
else:
digc=0
if 8/remainderc<1:
digd=1
remainderd=(denaryno%8)
else:
digd=0
if 4/remainderd<1:
dige=1
remaindere=(denary%4)
else:
dige=0
if 2/remaindere<1:
digf=1
remainderf=(denary%2)
else:
digf=0
if 1/remainderf<1:
digg=1
remainderg=(denary%1)
else:
digg=0
print (str(diga)+str(digb))
You only set digc in one of the top if/else statement. If 32/denaryno<1 is True, you don't set digc at all.
Set digc at the top of the function (to 0 or whatever else you want it to be). This applies to all the digit variables, digd, dige, etc.
What you really should do, instead, is use a list of digits, and append either a 0 or a 1 to that list every time you divide the number by a factor.
You may want to take a look at the divmod() function; it returns both the quotient and the remainder. You could also do with some looping here to slash the number of if statements needed here:
number = int(input("Write a number from 1-64 "))
digits = []
factor = 64
while number:
quotient, number = divmod(number, factor)
digits.append(quotient)
factor //= 2
print(''.join(map(str, digits)))
Wow that was a lot of work, you don't have to do all that.
def bin_convert(x, count=8):
return "".join(map(lambda y:str((x>>y)&1), range(count-1, -1, -1)))
here are the functions comprising this one from easy->important
str() returns a string
range() is a way to get a list from 1 number to another. Written like this range(count-1, -1, -1) counts backwards.
"".join() is a way to take an iterable and put the pieces together.
map() is a way to take a function and apply it to an iterable.
lambda is a way to write a function in 1 line. I was being lazy and could have written another def func_name(y) and it would have worked just as well.
>> is a way to shift bits. (which I believe understanding this one is the key component to understanding your problem)