I have a list that extends on like this and I would like to sort them based on the first 2 digits of the second part of each. I'm really rushed right now so some help would be nice.
collection = ["81851 19AJA01", "68158 17ARB03", "104837 20AAH02",
I tried this and it didn't work. I'm not doing this for a class I'd really appropriate some help
for x in collection:
counter = 0
i=0
for y in len(str(x)):
if (x[i] == '1'):
counter == 1
elif (x[i] == '2'):
counter == 2
elif x[i] == '0' and counter == 2:
counter = 2
elif x[i] == '9' and counter == 1:
counter = 3
elif x[i] == '8' and counter == 1:
counter = 4
elif x[i] == '7' and counter == 1:
counter = 5
i = i + 1
if (counter==2):
freshmen.append(x)
elif (counter==3):
sophomores.append(x)
elif (counter==4):
juniors.append(x)
elif (counter==5):
seniors.append(x)
Use the key function to define a custom sorting rule:
In [1]: collection = ["81851 19AJA01", "68158 17ARB03", "104837 20AAH02"]
In [2]: sorted(collection, key=lambda x: int(x.split()[1][:2]))
Out[2]: ['68158 17ARB03', '81851 19AJA01', '104837 20AAH02']
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 days ago.
This post was edited and submitted for review 2 days ago.
Improve this question
class Hand:
def __init__(self, hand):
self.hand = hand
def rank_to_index_converter(rank):
if rank == 2:
return 0
elif rank == 3:
return 1
elif rank == 4:
return 2
elif rank == 5:
return 3
elif rank == 6:
return 4
elif rank == 7:
return 5
elif rank == 8:
return 6
elif rank == 9:
return 7
elif rank == 10:
return 8
elif rank == 'J':
return 9
elif rank == 'Q':
return 10
elif rank == 'K':
return 11
elif rank == 'A':
return 1
else:
raise ValueError
def suit_to_index_converter(suit):
if suit == 'C':
return 0
elif suit == 'D':
return 1
elif suit == 'H':
return 2
elif suit == 'S':
return 3
else:
raise ValueError
def is_consecutive(hand):
### BEGIN YOUR SOLUTION
first = 0
string = ""
count = 0
for x in hand:
#print(x[0])
if x[0] == ("J"):
if first != 10 and (count != 0):
return False
string = x[0]
elif x[0] == ("Q"):
if string != "J" and (count != 0):
return False
string = x[0]
elif x[0] == ("K"):
if string != "Q" and (count != 0):
return False
string = x[0]
elif x[0] == ("A"):
if string != "K" and (count != 0):
return False
string = x[0]
elif x[0] != ("J" or "Q" or "K" or "A"):
if (x[0] != (first + 1)) and (count != 0):
if (hand[0][0] != "A"):
return False
first = x[0]
count = count + 1
return True
def is_suit(hand):
suit = hand[0][1]
for x in hand:
if x[1] != suit:
return False
return True
def is_flush(hand):
return is_suit(hand) and not is_consecutive(hand)
def is_four_of_a_kind(hand):
count = 0
pair_num = 0
lst = [0 for i in range(13)]
for x in hand:
index = rank_to_index_converter(x[0])
lst[index] += 1
for x in lst:
if x == 4:
return True
return False
def is_full_house(hand):
count = 0
pair_num = 0
lst = [0 for i in range(13)]
for x in hand:
index = rank_to_index_converter(x[0])
lst[index] += 1
three_pair = False
pair = False
for x in lst:
if x == 3:
three_pair = True
if x == 2:
pair = True
if three_pair and pair:
return True
return False
def is_flush(hand):
count = 0
while count < (len(hand) - 2):
if hand[count][1] != hand[count + 1][1]:
return False
count += 1
return True
def is_straight(hand):
if is_consecutive(hand) and not is_suit(hand):
return True
return False
def is_three_of_a_kind(hand):
lst = [0 for i in range(13)]
for x in hand:
index = rank_to_index_converter(x[0])
lst[index] += 1
three_pair = False
for x in lst:
if x == 3:
three_pair = True
if three_pair and not is_full_house(hand) and not is_suit(hand):
return True
return False
def is_two_pair(hand):
lst = [0 for i in range(13)]
for x in hand:
index = rank_to_index_converter(x[0])
lst[index] += 1
two_pair = False
counter = 0
switch = 0
while counter != len(lst):
if lst[counter] == 2:
switch = 1
if lst[counter] == 2 & switch == 1:
two_pair = True
if two_pair and not is_full_house(hand) and not is_suit(hand) and not is_four_of_a_kind(hand) and not is_three_of_a_kind(hand):
return True
return False
def is_pair(hand):
lst = [0 for i in range(13)]
for x in hand:
index = rank_to_index_converter(x[0])
lst[index] += 1
pair = False
for x in lst:
if x == 2:
pair = True
if pair and not is_full_house(hand) and not is_suit(hand):
return True
return False
def maximum_value(hand):
sum = 0
for x in hand:
sum += rank_to_index_converter(x[0])
return sum
The is_full_house function uses the rank_to_index_converter function. The rank_to_index_converter function is defined above the is_full_house function. Why am I receiving an error that the rank_to_index_converter function is not defined?
I am lost on where to proceed; therefore, I haven't tried anything, besides copying and pasting the rank_to_index_converter function into the is_full_house function; however, it is more convenient if the rank_to_index_converter is a separate function. That is why I want to solve this issue.
I want to implement basic calculator only includes numbers, '+' and '-' in Python. But I found that I cannot change index i inside the while loop.
def basicCalculator(expression):
res = 0
sign = 1
i = 0
while i < len(expression): # using while loop here
if expression[i] == '+':
sign = 1
elif expression[i] == '-':
sign = -1
elif '0' <= expression[i] <= '9':
temp = int(expression[i])
while i + 1 < len(expression) and '0' <= expression[i + 1] <= '9':
i += 1 # want to increase i, but failed
temp = temp * 10 + int(expression[i])
res += sign * temp
return res
s = "2+3-999"
print(basicCalculator(s)) # ouput should be -994, but infinite
Then I tried another way: using for loop instead of while loop, get incorrect answer.
def basicCalculator(expression):
res = 0
sign = 1
for i in range(len(expression)): # using for loop
if expression[i] == '+':
sign = 1
elif expression[i] == '-':
sign = -1
elif '0' <= expression[i] <= '9':
temp = int(expression[i])
while i + 1 < len(expression) and '0' <= expression[i + 1] <= '9':
i += 1 # increase i
temp = temp * 10 + int(expression[i])
res += sign * temp
return res
s = "2+3-999"
print(basicCalculator(s)) # ouput should be -994, but got -1102
I don't know why I cannot change the index inside the while loop or for loop. It is not a good idea to change i in for loop. What is the best way to fix the bug?
(I wrote the same code in Java using approach 2, everything is good, any difference?)
Rather than incrementing the index in a loop within the loop, I suggest just accumulating the current number in the main loop so you have less to keep track of:
def basicCalculator(expression):
res = 0
sign = 1
num = ""
for c in expression:
if c.isdecimal():
num += c
continue
res += int(num) * sign
num = ""
if c == "+":
sign = 1
elif c == "-":
sign = -1
else:
raise ValueError(f"Invalid operator {c}")
return res + int(num) * sign
print(basicCalculator("2+3-999")) # -994
I'm making a discord bot, i already made a dice rolling systen, but I want to improve it. I want to roll multiple dices at once, like Avrae can do.
#client.command(aliases=['r', 'dado', 'dice'])
async def roll(ctx, dados='', numero=20, conta='', ficha=''):
rolagem = random.randint(1,int(numero))
if conta == '':
total = (int(rolagem))
elif conta == '+':
total = (int(rolagem) + int(ficha))
elif conta == '-':
total = (int(rolagem) - int(ficha))
elif conta == 'x':
total = (int(rolagem) * int(ficha))
elif conta == '/':
total = (int(rolagem) / int(ficha))
if ficha == '':
ficha = ''
if total < 0:
total = '1'
if total == 0:
total == '1'
if rolagem == 20:
rolagem = '**20**'
if rolagem == 1:
rolagem = '**1**'
await ctx.send(f'{ctx.author.mention} 🎇 \n**Resultado**: D{numero} ({rolagem}) {conta} {ficha}\n**Total**: {total}')
So, the command should work like: (prefix)r (number of dices to roll) (dice), and show the results like: (number of dices rolled):(dices results)(sum of the dices result)
For exemple: -r 5 d20; Results for 5 D20:(1, 5, 8, 16, 20) (sum).
I want to know how I shoul do it
Here is a roll function I wrote, modified to use strings like you did:
import random
def roll(n='1', d='20', a='+', m='0'):
res = []
for i in range(int(n)):
res.append(random.randint(1, int(d)))
roll_modified = sum(res)
if a == '+' or a == '-' or a == '*' or a == '/':
roll_modified = eval('{}{}{}'.format(roll_modified, a, int(m)))
if roll_modified < 1:
roll_modified = 1
return roll_modified, res
It uses eval to apply the modifiers, so use with caution. I check the value of the operator and use int() on the number to ensure it is a safe expression.
Use it like this:
roll_modified, res = roll('3', '20', '-', '2')
roll_modified is the result after applying sum and modifiers.
res is a list of all the original rolls
You could then print your results with:
res_str = ["**{}**".format(x) if x == 20 or x == 1 else str(x) for x in res]
print(roll_modified, "[{}]".format(", ".join(res_str)))
will output:
36 [14, 4, **20**]
the problem I'm trying to solve is this Codewars kata: https://www.codewars.com/kata/58678d29dbca9a68d80000d7/train/python
I'm passing 123 out of 124 tests, but the one I'm failing is related to how I'm handling nested loops. I just can't seem to figure out a way to replicate the problem because they don't show you the test input. Any help is appreciated; here's what I have for the problem so far:
import re
def interpreter(code, tape):
#Filter out non-command characters
code_pure = re.findall(r"(\>|\<|\*|\[|\])", code)
sf = "".join(code_pure)
#Convert tape to list so that elements are mutable
tape_list = []
for bit in tape:
tape_list.append(bit)
#Keep track of pointer and instruction position
pointer = 0
instr = 0
brack_pos = [] #Contains positions of "[" brackets
while instr < len(sf):
#If pointer goes out of bounds then end the program
if pointer >= len(tape_list) or pointer < 0:
return "".join(tape_list)
#"*" flips the current bit
if sf[instr] == "*":
if tape_list[pointer] == "1":
tape_list[pointer] = "0"
elif tape_list[pointer] == "0":
tape_list[pointer] = "1"
instr += 1
#Move right one bit
elif sf[instr] == ">":
pointer += 1
instr += 1
#Move left one bit
elif sf[instr] == "<":
pointer -= 1
instr += 1
elif sf[instr] == "[":
#If pointer is on 0, skip the loop
if tape_list[pointer] == "0":
brack_cnt = 1
while brack_cnt != 0:
instr += 1
if sf[instr] == "[":
brack_cnt += 1
elif sf[instr] == "]":
brack_cnt -= 1
instr += 1
#If pointer is 1, step into the loop
elif tape_list[pointer] != "0":
brack_pos.append(instr)
instr += 1
elif sf[instr] == "]":
if tape_list[pointer] == "0":
instr += 1
elif tape_list[pointer] != "0":
instr = brack_pos[-1]
brack_pos.pop()
return "".join(tape_list)
The problem is in the last if-block checking for sf[instr] == "]" where brack_pos.pop() is executed only when looping back to the opening bracket, not when moving past the closing bracket. I.e. brack_pos.pop() needs to be unconditional.
Seems like a fun exercise btw., here's what I came up with:
def interpreter(code, tape):
# Implement your interpreter here
tape = list(tape)
# Find matching brackets
jump = [0]*len(code)
open_bracket_stack = []
for i,c in enumerate(code):
if c == '[':
open_bracket_stack.append(i)
elif c == ']':
matching = open_bracket_stack.pop()
jump[i] = matching
jump[matching] = i
code_ptr = 0
tape_ptr = 0
while(code_ptr < len(code) and tape_ptr < len(tape) and tape_ptr >= 0):
c = code[code_ptr]
if c == '>':
tape_ptr += 1
elif c == '<':
tape_ptr -= 1
elif c == '*':
tape[tape_ptr] = '1' if tape[tape_ptr] == '0' else '0'
elif c == '[' and tape[tape_ptr] == '0':
code_ptr = jump[code_ptr]
elif c == ']' and tape[tape_ptr] == '1':
code_ptr = jump[code_ptr]
code_ptr += 1
return "".join(tape)
I recently decided to try to code "yet another" brainfuck interpreter, but I have a problem. It prints out the wrong numbers, when it should put our hello,world!. Does anyone know why this is happening? Thanks in advance! I cannot figure out why it's doing this. Please help! I am only a beginner. Sorry for the bad coding style, but please don't change the whole thing. I would rather recieve tips.
from copy import copy
import sys
def brainfuckintepreter(program):
# find pairs of brackets
brackets = {}
bbrackets = {}
def findmatchingclosingbracket(ctr):
level = 0
if program[ctr] == '[':
while True:
if program[ctr] == '[':
level += 1
elif program[ctr] == ']':
level -= 1
if level == 0:
return ctr
break
ctr += 1
def findmatchingopeningbracket(ctr):
level = 0
if program[ctr] == ']':
while True:
if program[ctr] == '[':
level -= 1
elif program[ctr] == ']':
level += 1
if level == 0:
return ctr
break
ctr -= 1
"""
ctr = 0
for a in program:
if a == '[':
f = copy(findmatchingclosingbracket(ctr))
brackets[ctr] = f
bbrackets[f] = ctr
ctr += 1
print(brackets)
print(bbrackets)
"""
# running the program
tape = [0] * 3000
pointer = 1500
counter = 0
results = ""
valid = True
while counter != len(program) and valid:
a = program[counter]
# move right
if a == '>':
if pointer == len(tape) - 1:
tape.append(0)
pointer += 1
# move left
elif a == '<':
if pointer == 0:
raise ValueError("On index ", counter, ", the program tried to move to -1 on the tape")
valid = False
return valid
else:
pointer -= 1
# increment
elif a == '+':
if tape[pointer] == 255:
tape[pointer] = 0
else:
tape[pointer] += 1
# decrement
elif a == '-':
if tape[pointer] == 0:
tape[pointer] = 255
else:
tape[pointer] -= 1
# output character
elif a == '.':
t = chr(tape[pointer])
results += t
print(t, end='')
# input character
elif a == ',':
tape[pointer] = ord(sys.stdin.read(1))
# opening bracket
elif a == '[':
if tape[pointer] == 0:
pointer = findmatchingclosingbracket(pointer)
# closing bracket
elif a == ']':
if tape[pointer] != 0:
pointer = findmatchingopeningbracket(counter)
counter += 1
"""
for b in tape:
if b != 0:
print(b)
"""
brainfuckintepreter('++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.')
Edit:
I changed my code after some revisions, but same problem.
Your loops are the problem.
level = 0
while level > 0:
...
That loop will never be entered. The condition is immediately false (you're setting level to 0, right before checking if it is greater than 0).
You could change that to a do..while loop instead of a while loop (make a while true loop and check the condition at the end to decide whether to break out of the loop or not) and start checking at the current pointer position (include the current [ or ]), not at the next character after it.
Also here:
if tape[pointer] == 0:
pointer = findmatchingclosingbracket(pointer)
you should be passing and updating the program counter, not the tape pointer on the second line. And likewise for the other one just below it.