Issues with if iv1 >= hpmin: ; hpmin = iv1 - python-3.x

I apologize for the rather vague title, I couldn't think of a good way to describe this issue. Basically I have
def collectivs():
while True:
a = input('Input format IVtype X-Y where X is the lowest possible IV and Y is the highest.\nIV types are:[HP, ATK, DEF, SPA, SPD, SPE]\n')
hpmin = 0
hpmax = 31
hp = "%s-%s" % (hpmin, hpmax)
try:
ivtypeup, ivrange = a.split(' '); ivtype = str.lower(ivtypeup)
print(ivtype, ivrange)
if ivtype not in('hp''atk''def''spa''spd''spe'):
print('k')
else:
print('k its working')
nonintivs = ivrange.split('-')
iv1, iv2 = list(map(int, nonintivs))
print(type(iv1))
if ivtype == 'hp':
if iv1 >= hpmin:
hpmin = iv1
if iv2 < hpmax:
hpmax = iv2
else:
print('k')
more specifically I'm trying to say "if iv1 is greater than hpmin, change hpmin to iv1." and then repeat this multiple times so I can enter say:
hp 23-31
hp 22-29
and then the result would be:
hp 23-29 because 29 is less than hp hpmax and 23 is more than the iv1 inputted in the second input. The problem is it's not doing that, in the example above if I input those the final result would be 22-29, even though it should be 23-29.
I can't think of a better way to describe it, but I've been staring at this code for an hour trying to figure out what's wrong with it, and being a beginner I can't quite figure it out.

You need to move the hpmin and hpmax initial assignments outside of the while loop:
hpmin = 0
hpmax = 31
Before-and-after diff here

Related

Why does my solution to problem 3 of the CodeJam 2020 Qualification Round not work?

I would like to receive help in understanding why my solution to Problem 3 of the Google CodeJam 2020 Qualifier does not work.
Link to problem: https://codingcompetitions.withgoogle.com/codejam/round/000000000019fd27/000000000020bdf9
My solution:
High-level overview:
take input
figure out if the given input is impossible by sorting according to start times and then checking if more than 2 subsequent activities are 'active' at once (which is impossible)
if it is, output accordingly; if it isn't, proceed with the procedure below
arbitrarily assign the first person: in my solution I choose Cameron (C).
next, since we know that a solution exists, and the array I iterate through is sorted according to start times, if the very next activity interval (chronologically) overlaps in its duration with the current, assign it to the person who is not currently busy. This is purely because a solution exists, and it clearly cannot be the current person, so it must be the other.
moreover, if the very next activity interval (chronologically) does not overlap with the current activity, then assign it to the person who is currently busy (because he will not be busy for the next activity)
in addition, quoted directly from the problem's official analysis: "If an assignment is possible, there cannot be any set of three activities that pairwise overlap, so by the contrapositive of the the previous argument, we will be able to assign the activity to at least one of Jamie or Cameron at every step."
At this moment, I believe that these arguments suffice to show that my logic is valid, although my code evidently does not always produce the correct answer. I would greatly appreciate any help on this, since I have spent hours trying to debug, un-reason, or find a counter-example to my code to no avail. I have included my code, for reference, below.
Code:
for p in range(int(input())):
s = int(input())
l = []
for i in range(s):
l.append(list(map(int, list(input().split()))))
unsort = l.copy()
l = sorted(l, key=lambda tup: (tup[0],tup[1]))
enumerated = list(enumerate(unsort))
enumerated.sort(key=lambda x: x[1][0])
impossible = False
endings = sorted([(x[1], False) for x in unsort])
startings = sorted([(x[0], True) for x in unsort])
total = sorted(endings + startings, key=lambda tup: (tup[0], tup[1]))
size = 0
for i in total:
if i[1] == True:
size += 1
else:
size -= 1
if size > 2:
impossible = True
def overlap(a,b):
if not max(a[0], b[0]) >= min(a[1], b[1]):
return True
else:
return False
ans = "C"
def opp(a):
if a == "C":
return "J"
else:
return "C"
if impossible == True:
print("Case #" + str(p+1) + ": " + "IMPOSSIBLE")
else:
for i in range(0, s-1):
if overlap(l[i], l[i+1]) == True:
ans = ans + opp(ans[len(ans)-1])
else:
ans = ans + opp(opp(ans[len(ans)-1]))
#the stuff below is to order the activity assignments according to input order
key_value = [(ans[i], l[i]) for i in range(s)]
fans = ""
for i in range(s):
for j in range(s):
if enumerated[j][0] == i:
fans = fans + key_value[j][0]
print("Case #" + str(p + 1) + ": " + fans)

Hangman: Registering as correct after only a few correct guesses

When I run this, after a few correct guesses it prints Prisoner Wins!
Does anyone know why?
num_letters=int(input('How many letters?'))
word_to_guess = []
for _ in range(num_letters):
word_to_guess.append(
input('Input your (lowercase) letter:').lower().strip())
word_to_show = ['?', ] * num_letters
fail = 0
good = 0
while fail < 7 and good < num_letters:
guess = input('Guess a letter...').lower().strip()
if guess in word_to_guess:
print('Right!')
good += 1
for i, letter in enumerate(word_to_guess):
if guess == letter:
good+=1
word_to_show[i] = letter
else:
print('No.')
fail += 1
print(word_to_show)
print('word_to_guess', word_to_guess)
print('word_to_show', word_to_show)
if fail == 7:
print('Executioner wins!')
else:
print('Prisoner wins!')
The discrepancy is inconsistent. I tried it multiple times and it ranged from 2 to 6. One other thing: this code was provided by Ralf.

Check if number has a digit multiple times

I've come across a puzzling challenge. I have to check if a number contains the same digit multiple times ex. 11, 424, 66 and so on. at first this seems easy enough but i'm having trouble coming up with a logic to check for this. any ideas?
This is what I've got so far. the function takes in a list. (updated)
arr = [[1,20],[1,10]]
for i in arr:
l = list(range(i[0],i[1]))
for num in l:
if num < 11: continue
for c in str(num):
if str(num).count(c) > 1:
# dont know why code is popping off 12 and 13
print(l.pop(num))
If your ultimate goal is simply detecting if there's a double, this function may help:
def has_doubles(n):
return len(set(str(n))) < len(str(n))
The best way I can think about is converting the number to a string and doing a Counter on it
from collections import Counter
a = 98
c = Counter(str(a))
if any(value > 1 for value in c.values()):
print "The number has repeating digits"
#Two-BitAlchemist thanks for the suggestion
looks like you wanted to create your own algorithm probably researching or a student practice well you just have to understand the properties of numbers divided by 10 where 1/10 = 0.1 10/10 = 1 13/10 = 1 reminder 3 13013/10 = 1301 rem 3 hence we can create a function that stores the reminders in an array an check them against the reminder of next number here is the algorithm in python using recursion, you can achieve the same via loops
def countNumber(foundDigits,number):
next_number = int(number/10);
reminder = number % 10;
if(next_number < 1):
for num in foundDigits:
if(num == number or num == reminder):
return True
return False;
foundDigits.append(reminder);
return countNumber(foundDigits,next_number)
example in interpreter could be
digitsFound = list()
countNumber(digitsFound, 435229)
Solved this! I didn't know pop executes based on position not value! remove is a better fit here.
arr = [[1,40],[1,10]]
for i in arr:
l = list(range(i[0],i[1]))
for num in l:
if num < 11: continue
for char in str(num):
if str(num).count(char) < 2: continue
l.remove(num)
break
print(l)
Here is my solution, its simple and works for 2 digit numbers.
nums = list(input().rstrip().split())
def has_doubles(nums):
for number in nums:
if number[0] == number[1]:
print(number)
else:
continue
has_doubles(nums)

Beginner Python: Where to "while"?

tl;dr: My code "works", in that it gives me the answer I need. I just can't get it to stop running when it reaches that answer. I'm stuck with scrolling back through the output.
I'm a complete novice at programming/Python. In order to hone my skills, I decided to see if I could program my own "solver" for Implied Equity Risk Premium from Prof. Damodaran's Valuation class. Essentially, the code takes some inputs and "guesses and tests" a series of interest rates until it gets a "close" value to the input.
Right now my code spits out an output list, and I can scroll back through it to find the answer. It's correct. However, I cannot for the life of me get the code to "stop" at the correct value with the while function.
I have the following code:
per = int(input("Enter the # of periods forecast ->"))
divbb = float(input("Enter the initial dividend + buyback value ->"))
divgr = float(input("Enter the div + buyback growth rate ->"))
tbondr = float(input("Enter the T-Bond rate ->"))+0.000001
sp = int(input("Enter the S&P value->"))
total=0
pv=0
for i in range(1,10000):
erp = float(i/10000)
a = divbb
b = divgr
pv = 0
temppv = 0
print (sp-total, erp)
for i in range(0, per):
a=a * (1+b)
temppv = a / pow((1+erp),i)
pv=pv+temppv
lastterm=(a*1+tbondr)/((erp-tbondr)*pow(1+erp,per))
total=(pv+lastterm)
From his example, with the inputs:
per = 5
divbb = 69.46
divgr = 0.0527
tbondr = 0.0176
sp = 1430
By scrolling back through the output, I can see my code produces the correct minimum at epr=0.0755.
My question is: where do I stick the while to stop this code at that minimum? I've tried a lot of variations, but can't get it. What I'm looking for is, basically:
while (sp-total) > |1|, keep running the code.
per = 5
divbb = 69.46
divgr = 0.0527
tbondr = 0.0176
sp = 1430
total=0
pv=0
i = 1
while(abs(sp-total)) > 1:
erp = i/10000.
a = divbb
b = divgr
pv = 0
temppv = 0
print (sp-total, erp)
for j in range(0, per):
a=a * (1+b)
temppv = a / pow((1+erp),j)
pv=pv+temppv
lastterm=(a*1+tbondr)/((erp-tbondr)*pow(1+erp,per))
total=(pv+lastterm)
i += 1
should work. Obviously, there are a million ways to do this. But the general gist here is that the while loop will stop as soon as it meets the condition. You could also test every time in the for loop and include a break statement, but because you don't know when it will stop, I think a while loop is better in this case.
Let me give you a quick rundown of two different ways you could solve a problem like this:
Using a while loop:
iterator = start value
while condition(iterator):
do some stuff
increment iterator
Using a for loop:
for i in xrange(startvalue, maxvalue):
do some stuff
if condition:
break
Two more thing: if you're doing large ranges, use the generator xrange. Also, it's probably a bad idea to reuse i inside your for loop.
I recommend CS101 from Udacity.com for learning Python. Also, if you're interested in algorithms, work through the problems at projecteuler.com

Binary search code not working

Good afternoon everyone,
I'm trying to sort out names which are already sorted in alphabetical order. I can't figure out why my program isn't working. Any tips or pointers would be nice. Thanks.
def main():
names = ['Ava Fiscer', 'Bob White', 'Chris Rich', 'Danielle Porter', 'Gordon Pike', 'Hannah Beauregard', 'Matt Hoyle', 'Ross Harrison', 'Sasha Ricci', 'Xavier Adams']
input('Please enter the name to be searched: ', )
binarySearch
main()
def binarySearch(names):
first = 0
last = len(names) - 1
position = -1
found = False
while not found and first <= last:
middle = (first + last) / 2
if names[middle] == value:
found = True
position = middle
elif arr[middle] > value:
last = middle -1
else:
first = middle + 1
return position
What does it mean that the program isn't working? Is it a syntax error or is the problem in the wrong results?
With the code you pasted, there are several indentation problems, but besides that, lines:
input('Please enter the name to be searched: ', )
binarySearch
are also syntactically incorrect, the comma is redundant and only the function name appearing just like that is plain wrong. If you are interested in the correctness of your algorithm, it seems alright, but the boundaries can always be tricky. My code below is working and syntactically correct, if you find it helpful. (names are numbers, but that is irrelevant in this case)
names = [1,2,4,5,6,8,9]
def bs(n):
start = 0
end = len(names)
while end - start > 0:
m = (start+end)/2
if names[m] == n:
return m
elif n < names[m]:
end = m
else:
start = m + 1
return -1
print (bs(1))
print (bs(6))
print (bs(9))
print (bs(3))
print (bs(10))
print (bs(-8))
Another thing I would like to point out is that this kind of binary search is already in the python standard library, the bisect module. However, if you are writing your own for practice or for any other reason that is just fine.
if you are using python 3.* then you are going to want to change
m = (start+end)/2
to
m = (start+end)//2
When you do /2 it outputs a float in 3.*

Resources