Python 3.x runs in IDLE but has issues in Pycharm - debugging

I'm new to Stack Overflow and Python.
I've been teaching myself Python 3 for the last couple of weeks using IDLE to create my code which has been working great. I recently decided to download and install the community version of PyCharm. Here's my issue...
I've been using the import random and random.randint() command to generate numbers. When I opened my last Python project, which worked fine in IDLE, into PyCharm and tried to run it, it gave me back two errors.
When I use the "Debug" command in PyCharm, the program runs fine but when I use the "Run" function it gives me two errors.
Here's my code:
import random
# Megamillion Generator
def mega():
s = []
a = random.randint(start, finish)
b = random.randint(start, finish)
c = random.randint(start, finish)
d = random.randint(start, finish)
e = random.randint(start, finish)
s.append(a)
s.append(b)
s.append(c)
s.append(d)
s.append(e)
s.sort()
if x < 10:
print("Random ", str(i), " ", end="")
print(s)
print("Sorted ", end="")
print(end=" ")
print(s)
else:
print("Random", str(i), end="")
print(s)
s.sort()
print("Sorted ", end="")
print(end="")
print(s)
return s
# 3 digit Generator
def digit_3():
s = []
a = random.randint(0, 9)
b = random.randint(0, 9)
c = random.randint(0, 9)
s.append(a)
s.append(b)
s.append(c)
print(format, "Random {0:2}")
print((i), end="")
print(s)
s.sort()
print("Sorted", end="")
print(end=" ")
print(s)
return s
# 4 digit Generator
def digit_4():
s = []
a = random.randint(0, 9)
b = random.randint(0, 9)
c = random.randint(0, 9)
d = random.randint(0, 9)
s.append(a)
s.append(b)
s.append(c)
s.append(d)
print("Random ", end="")
print((i), end="")
print(s)
s.sort()
print("Sorted", end="")
print(end=" ")
print(s)
return s
# Begin Generator
gentype = str(input("Enter '3' for 3-digit, '4' for 4-digit, 'm' for Megamillion or 'all' for all three"))
x = int(input("Enter a number "))
x = x + 1
if gentype == '3':
for i in range(1, x):
digit_3()
elif gentype == '4':
for i in range(1, x):
digit_4()
else:
start = int(input("Enter smallest number to generate "))
finish = int(input("Enter highest number to generate "))
for i in range(1, x):
mega()
And here's the error msg:
line 1, in <module>
import random
line 5, in <module>
a=random.randint(1,70)
AttributeError: module 'random' has no attribute 'randint'
Any Help would be greatly appreciated.

Related

How can I compare lists properly?

So I am trying to teach myself some coding and decided to create a little lotto simulator but I just cannot manage to get the program to compare my four lists properly, what is the matter with my def compList code?.
from random import randint as rnd
myGuess_list = []
myGuess_normal = []
myGuess_bonus = []
numbers =[]
drawNumbers = []
normalNumbers = []
bonusNumbers = []
normal_correct = 0
bonus_correct = 0
CORRECT_list = []
BONUS_list = []
winnings = 0
def main():
# generate list of possible numbers
i = 0
for i in range(0, 34):
i += 1
numbers.append(i)
print(numbers)
# draw random numbers from list as lists guessed
def myGuess():
for i in range(0, 10):
numbers = rnd(1, 34)
while numbers in myGuess_list:
numbers = rnd(1, 34)
myGuess_list.append(numbers)
myGuess_list.sort()
myGuess_normal = myGuess_list[0:7]
myGuess_bonus = myGuess_list[-3:]
return myGuess_normal, myGuess_bonus
print(myGuess())
# drawing the lotto numbers from the pool of numbers
def drawNumber(numbers, N):
for i in range(0, N):
number = random.choice(numbers)
while number in drawNumbers:
number = random.choice(numbers)
drawNumbers.append(number)
drawNumbers.sort()
normalNumbers = drawNumbers[0:7]
bonusNumbers = drawNumbers[-3:]
return normalNumbers, bonusNumbers
print(drawNumber(numbers, 10))
comparing list drawn list A with guessed list B and drawn list C with guessed list D
def compList(A, B, C, D):
global normal_correct
global bonus_correct
for i in A and j in C:
if i in B:
normal_correct += 1
CORRECT_list.append(i)
elif j in D:
bonus_correct += 1
BONUS_list.append(j)
print(CORRECT_list + BONUS_list)
return normal_correct, bonus_correct
print(compList(normalNumbers, myGuess_normal, bonusNumbers, myGuess_bonus))
calculate winnings base on previous function
def Winnings(normal_correct, bonus_correct):
global winnings
i = 0
for i in range(0, 10):
i += 1
if normal_correct <= 3:
winnings = 0 - 5
elif normal_correct == 4:
winnings = 45 - 5
elif normal_correct == 5:
winnings = 100 - 5
elif normal_correct == 6:
winnings = 3695 - 5
elif normal_correct == 6 and bonus_correct == 1:
winnings = 169410 - 5
elif normal_correct == 7:
winnings = 'JACKPOT!!'
return winnings
print(Winnings(normal_correct, bonus_correct))
calling main
main()

Is there a known algorithm for simplifying a boolean expression with number comparisons?

For example, if I have the expression (A > 5) && (A == 6),
that expression can be simplified to just (A == 6), and still have the same behavior for A ∈ ℤ.
I also need it to work with multiple variables, so for instance ((B > 2) && (C == 2)) || ((B > 2) && (C < 2)) should simplify to (B > 2) && (C < 3).
I won't need to compare two unknowns, only unknowns and numbers, and I only need it to work with the operators <, >, and == for numbers, and && and || for expressions (&& being AND and || being OR, of course). All unknowns are integers.
Is there any algorithm that takes such an expression and returns an expression with equal behavior and a minimal amount of operators?
(in my specific case, || operators are preferred over &&)
Here's a slow dynamic programming algorithm along the lines that you were thinking of.
from collections import defaultdict, namedtuple
from heapq import heappop, heappush
from itertools import product
from math import inf
# Constructors for Boolean expressions. False and True are also accepted.
Lt = namedtuple("Lt", ["lhs", "rhs"])
Eq = namedtuple("Eq", ["lhs", "rhs"])
Gt = namedtuple("Gt", ["lhs", "rhs"])
And = namedtuple("And", ["lhs", "rhs"])
Or = namedtuple("Or", ["lhs", "rhs"])
# Variable names. Arbitrary strings are accepted.
A = "A"
B = "B"
C = "C"
# Example formulas.
first_example = And(Gt(A, 5), Eq(A, 6))
second_example = Or(And(Gt(B, 2), Eq(C, 2)), And(Gt(B, 2), Lt(C, 2)))
third_example = Or(And(Gt(A, 1), Gt(B, 1)), And(Gt(A, 0), Gt(B, 2)))
fourth_example = Or(Lt(A, 6), Gt(A, 5))
fifth_example = Or(And(Eq(A, 2), Gt(C, 2)), And(Eq(B, 2), Lt(C, 2)))
# Returns a map from each variable to the set of values such that the formula
# might evaluate differently for variable = value-1 versus variable = value.
def get_critical_value_sets(formula, result=None):
if result is None:
result = defaultdict(set)
if isinstance(formula, bool):
pass
elif isinstance(formula, Lt):
result[formula.lhs].add(formula.rhs)
elif isinstance(formula, Eq):
result[formula.lhs].add(formula.rhs)
result[formula.lhs].add(formula.rhs + 1)
elif isinstance(formula, Gt):
result[formula.lhs].add(formula.rhs + 1)
elif isinstance(formula, (And, Or)):
get_critical_value_sets(formula.lhs, result)
get_critical_value_sets(formula.rhs, result)
else:
assert False, str(formula)
return result
# Returns a list of inputs sufficient to compare Boolean combinations of the
# primitives returned by enumerate_useful_primitives.
def enumerate_truth_table_inputs(critical_value_sets):
variables, value_sets = zip(*critical_value_sets.items())
return [
dict(zip(variables, values))
for values in product(*({-inf} | value_set for value_set in value_sets))
]
# Returns both constants and all single comparisons whose critical value set is
# a subset of the given ones.
def enumerate_useful_primitives(critical_value_sets):
yield False
yield True
for variable, value_set in critical_value_sets.items():
for value in value_set:
yield Lt(variable, value)
if value + 1 in value_set:
yield Eq(variable, value)
yield Gt(variable, value - 1)
# Evaluates the formula recursively on the given input.
def evaluate(formula, input):
if isinstance(formula, bool):
return formula
elif isinstance(formula, Lt):
return input[formula.lhs] < formula.rhs
elif isinstance(formula, Eq):
return input[formula.lhs] == formula.rhs
elif isinstance(formula, Gt):
return input[formula.lhs] > formula.rhs
elif isinstance(formula, And):
return evaluate(formula.lhs, input) and evaluate(formula.rhs, input)
elif isinstance(formula, Or):
return evaluate(formula.lhs, input) or evaluate(formula.rhs, input)
else:
assert False, str(formula)
# Evaluates the formula on the many inputs, packing the values into an integer.
def get_truth_table(formula, inputs):
truth_table = 0
for input in inputs:
truth_table = (truth_table << 1) + evaluate(formula, input)
return truth_table
# Returns (the number of operations in the formula, the number of Ands).
def get_complexity(formula):
if isinstance(formula, bool):
return (0, 0)
elif isinstance(formula, (Lt, Eq, Gt)):
return (1, 0)
elif isinstance(formula, And):
ops_lhs, ands_lhs = get_complexity(formula.lhs)
ops_rhs, ands_rhs = get_complexity(formula.rhs)
return (ops_lhs + 1 + ops_rhs, ands_lhs + 1 + ands_rhs)
elif isinstance(formula, Or):
ops_lhs, ands_lhs = get_complexity(formula.lhs)
ops_rhs, ands_rhs = get_complexity(formula.rhs)
return (ops_lhs + 1 + ops_rhs, ands_lhs + ands_rhs)
else:
assert False, str(formula)
# Formula compared by complexity.
class HeapItem:
__slots__ = ["_complexity", "formula"]
def __init__(self, formula):
self._complexity = get_complexity(formula)
self.formula = formula
def __lt__(self, other):
return self._complexity < other._complexity
def __le__(self, other):
return self._complexity <= other._complexity
def __eq__(self, other):
return self._complexity == other._complexity
def __ne__(self, other):
return self._complexity != other._complexity
def __ge__(self, other):
return self._complexity >= other._complexity
def __gt__(self, other):
return self._complexity > other._complexity
# Like heapq.merge except we can add iterables dynamically.
class Merge:
__slots__ = ["_heap", "_iterable_count"]
def __init__(self):
self._heap = []
self._iterable_count = 0
def update(self, iterable):
iterable = iter(iterable)
try:
value = next(iterable)
except StopIteration:
return
heappush(self._heap, (value, self._iterable_count, iterable))
self._iterable_count += 1
def __iter__(self):
return self
def __next__(self):
if not self._heap:
raise StopIteration
value, index, iterable = heappop(self._heap)
try:
next_value = next(iterable)
except StopIteration:
return value
heappush(self._heap, (next_value, index, iterable))
return value
class Combinations:
__slots__ = ["_op", "_formula", "_best_formulas", "_i", "_n"]
def __init__(self, op, formula, best_formulas):
self._op = op
self._formula = formula
self._best_formulas = best_formulas
self._i = 0
self._n = len(best_formulas)
def __iter__(self):
return self
def __next__(self):
if self._i >= self._n:
raise StopIteration
formula = self._op(self._formula, self._best_formulas[self._i])
self._i += 1
return HeapItem(formula)
# Returns the simplest equivalent formula, breaking ties in favor of fewer Ands.
def simplify(target_formula):
critical_value_sets = get_critical_value_sets(target_formula)
inputs = enumerate_truth_table_inputs(critical_value_sets)
target_truth_table = get_truth_table(target_formula, inputs)
best = {}
merge = Merge()
for formula in enumerate_useful_primitives(critical_value_sets):
merge.update([HeapItem(formula)])
best_formulas = []
for item in merge:
if target_truth_table in best:
return best[target_truth_table]
formula = item.formula
truth_table = get_truth_table(formula, inputs)
if truth_table in best:
continue
n = len(best_formulas)
for op in [And, Or]:
merge.update(Combinations(op, formula, best_formulas))
best[truth_table] = formula
best_formulas.append(formula)
print(simplify(first_example))
print(simplify(second_example))
print(simplify(third_example))
print(simplify(fourth_example))
print(simplify(fifth_example))
Output:
Eq(lhs='A', rhs=6)
And(lhs=Lt(lhs='C', rhs=3), rhs=Gt(lhs='B', rhs=2))
And(lhs=And(lhs=Gt(lhs='B', rhs=1), rhs=Gt(lhs='A', rhs=0)), rhs=Or(lhs=Gt(lhs='B', rhs=2), rhs=Gt(lhs='A', rhs=1)))
True
Or(lhs=And(lhs=Eq(lhs='B', rhs=2), rhs=Lt(lhs='C', rhs=2)), rhs=And(lhs=Gt(lhs='C', rhs=2), rhs=Eq(lhs='A', rhs=2)))
Maybe you can consider intervals for your variables, for example:
(A > 5) && (A == 6)
Given you have a variable A, set an initial interval for it: A: [-∞, ∞].
Each condition that you read, you can reduce your interval:
(A > 5) sets the interval for A: [6, ∞]
(A == 6) sets the interval for A: [6, 6]
For each update on the interval, check if the new condition is possible, for example:
(A > 5) sets the interval for A: [6, ∞]
(A == 5) out of the interval, impossible condition.
Just another example:
((B > 2) && (C == 2)) || ((B > 2) && (C < 2))
Initially: B: [-∞, ∞] and C: [-∞, ∞].
((B > 2) && (C == 2))
(B > 2) sets the interval for B: [3, ∞]
(C == 2) sets the interval for C: [2, 2]
The next condition is attached with ||, so you add intervals:
((B > 2) && (C < 2))
(B > 2) sets the interval for B: [3, ∞]
(C < 2) sets the interval for C: [2, 2] U [-∞, 1] = [-∞, 2]

Algorithm Challenge number formatting problem

Invoice numbers are numeric only with any number of digits. To format one correctly, group the digits in group of three plus a group of any remainder, but never leave one digit by itself, unless it's a one digit number. Eg these are all correct formatting
123
12-34
6
783-907-23-45
And these are not
123-4
98-456
There's one more catch user input is passed directly to the function and you never know what characters users might type. Ignore any part of the input that is not digit
Invoice.format_number should always return a string
module Invoice
def self.format_number(str)
return ""
end
end
puts Invoice.format_number("ab1234")
What I have tried
1st approach
arr = []
str.chars.each do |elem|
val = elem =~ /\A[-+]?[0-9]*\.?[0-9]+\Z/
arr << elem if val == 0
end
num_of_digits = arr.length
pairs_of_two = 0
pairs_of_three = 0
if num_of_digits > 5
while num_of_digits > 0 do
break if num_of_digits <= 3
if num_of_digits >= 3 && (num_of_digits % 3 == 0 || num_of_digits % 3 == 2)
pairs_of_three += 1
num_of_digits -= 3
elsif num_of_digits % 2 == 0 || num_of_digits % 2 == 1
pairs_of_two += 1
num_of_digits -= 2
end
end
end
2nd approach
arr = []
str.chars.each do |elem|
val = elem =~ /\A[-+]?[0-9]*\.?[0-9]+\Z/
arr << elem if val == 0
end
len = arr.length - 1
if arr.length > 4
str = ""
i = 0
while i < len do
if arr[i..i+3].length == 4
str << arr[i..i+2].join + "-"
i += 3
elsif arr[i..i+2].length == 3
str << arr[i..i+1].join + "-"
i += 2
elsif arr[i..i+1].length == 2
str << arr[i..i+1].join
i += 2
elsif !arr[i].nil?
str << arr[i]
i += 1
end
end
puts str
else
if arr.length <= 3
puts arr.join
else
puts arr[0..1].join + "-" + arr[2..3].join
end
end
But none of them is correct
Here is the function invoice_number in python
def invoice_number(invoice):
s = ''.join(x for x in invoice if x <= '9' and x >= '0')
n = len(s)
if n <= 3:
return s
w = ''
i = 0
while i + 3 <= n:
for j in range(0, 3):
w += s[i + j]
i += 3
w += ('-')
m = n - i
if m == 0: return w[:-1]
if m == 1: return w[:m-3] + '-' + s[-2:]
return w + s[i:]
Testing
print(invoice_number('1234567'))
print(invoice_number('12345678'))
print(invoice_number('abc123456789'))
print(invoice_number('1234abc5678xyz9foobar'))
123-45-67
123-456-78
123-456-789
123-456-789
Eliminating non-digits is easy with re. For your format, the key is to figure our the "right" splitting indices.
Here is a try:
import re
def splits(n, k):
idx = [(i, min(n, i+k)) for i in range(0, n, k)]
if len(idx) > 1:
(a, b), (c, d) = idx[-2:]
if d - c < 2:
idx[-2:] = [(a, b - 1), (c - 1, d)]
return idx
def myformat(s):
s = re.sub(r'[^0-9]+', '', s)
parts = [s[a:b] for a, b in splits(len(s), 3)]
return '-'.join(parts)
Tests:
>>> myformat('123')
123
>>> myformat('1234')
12-34
>>> myformat('6')
6
>>> myformat('7839072345')
783-907-23-45
As the question was asked for ruby, adding solution for ruby. (The inspiration of the code is mostly from #yuri answer)
def format_invoice(invoice)
# only numbers are allowed
invoice = invoice.tr("^0-9","")
#puts invoice
return invoice if(invoice.length <= 3)
formatted_invoice = ''
i = 0
# Loop to divide the invoice in group of 3
while i + 3 <= invoice.length do
for j in 0..2 do
formatted_invoice += invoice[i + j]
end
i += 3
formatted_invoice += ('-')
end
m = invoice.length - i
return formatted_invoice[0..-2] if m == 0
return formatted_invoice[0..m-4] + '-' + invoice[-2..-1] if m == 1
return formatted_invoice + invoice[i..-1]
end
Testing
puts format_invoice('abc1') # 1
puts format_invoice('abc123') # 123
puts format_invoice('abc123A4') # 12-34
puts format_invoice('1234567') # 123-45-67
puts format_invoice('12345678') # 123-456-78
puts format_invoice('abc123456789') # 123-456-789
puts format_invoice('1234a#c5678xyz9foobar') # 123-456-789

Partial Fibonacci Sum, how to improve performance?

I need to improve the performance of this algorithm. I believe the answer lies in the application of the pisano period.
This algorithm must return the last digit of the sum of fib numbers from f(m) to f(n).
Here is what I have so far:
def fib(n)
a = []
a << 0 << 1
(n+1).times do |i|
a << a[-1] + a[-2]
end
a[n]
end
def fib_partial_sum(m, n)
if n == m
fib(m) % 10
else
m = fib(m + 1) - 1
n = fib(n + 2) - 1
(n - m) % 10
end
end
if __FILE__ == $0
m, n = gets.split().map(&:to_i)
puts "#{fib_partial_sum(m, n)}"
end
The last digit of any fib num repeats every 60 numbers. Therefore, we can do this, n, m = n % 60, m % 60. An improvement, but not quite there yet, fails on input 567717153638 567717153638):
def fib(n)
a = []
a << 0 << 1
(n+1).times do |i|
a << a[-1] + a[-2]
end
a[n]
end
def fib_partial_sum(m, n)
if n == m
fib(m)
else
m = m % 60
n = n % 60
m = fib(m + 1) - 1
n = fib(n + 2) - 1
(n - m) % 10
end
end
if __FILE__ == $0
m, n = gets.split().map(&:to_i)
puts "#{fib_partial_sum(m, n)}"
end
Here is a nice solution to the problem, it passes all time and memory constraints.
This way you never have to calculate a fib num greater that f(60). It can handle very large inputs efficiently.
def fib(n)
a, b = 0, 1
(n-1).times do
a, b = b, (a + b) % 10
end
b
end
def fib_partial_sum(m, n)
if n == m
fib(m % 60)
else
m = m % 60
n = n % 60
m = fib(m + 1) - 1
n = fib(n + 2) - 1
(n - m) % 10
end
end
if __FILE__ == $0
m, n = gets.split().map(&:to_i)
puts "#{fib_partial_sum(m, n)}"
end
(Max time used: 0.05/5.00, max memory used: 8699904/536870912.)
The following requires only a single pass of the numbers between zero and at most [n,m+60].min, where m..n is the range of interest, and has a minimal memory requirement. It makes use of #nloveladyallen's observation that the last digit of Fibonacci numbers has a periodicity of 60.
Code
def fib_last(m,n)
n -= 60*((n-m)/60)
fib_sum(m,n) % 10
end
def fib_sum(m,n)
return nil if m < 0 || m > n
return n if n < 2
next_to_last, last = fib(m-1)
(m..n).reduce(0) do |tot,_|
current = next_to_last + last
next_to_last = last
last = current
tot + current
end
end
def fib(m)
next_to_last, last = -1, 1
0.upto(m).each do |n|
current = next_to_last + last
next_to_last, last = last, current
end
[next_to_last, last]
end
Example
m, n = 6, 12
(n+1).times { |i| puts "#{i}: #{fib(i)}" }
0: [0, 0]
1: [0, 1]
2: [1, 1]
3: [1, 2]
4: [2, 3]
5: [3, 5]
6: [5, 8]
7: [8, 13]
8: [13, 21]
9: [21, 34]
10: [34, 55]
11: [55, 89]
12: [89, 144]
fib_last(6,12) #=> 4 (fib_sum(6,12) #=> 8 + 13 + 21 + 34 + 55 + 89 + 144 = 364)
fib_last(1,2) #=> 2 (fib_sum(1,2) #=> 1 + 1 = 2)
fib_last(1,3) #=> 4 (fib_sum(1,3) #=> 1 + 1 + 2 = 4)
fib_last(1,4) #=> 7 (fib_sum(1,4) #=> 1 + 1 + 2 + 3 = 7)
fib_last(2,3) #=> 3 (fib_sum(2,3) #=> 1 + 2 = 3)

My wxpython program suddenly doesn't work for no reason

I made a program for school few weeks ego.. i have finished it yet.
for some reason, when i am trying to run the program now, it doesn't work, although it worked well in the last time a tried.
I am sure that i didn't change anything in the code, but there is always a chance that something has changed and i didn't payed attention..
I need to pass it to my teacher in these days and i have no idea what is wrong with the program.
I will glad to get some help here..
here is the code:
import wx
import winsound
import wx.grid as gridlib
from random import randint
OPTIONS = [1, 2, 3, 4, 5, 6, 7, 8, 9, "DEL", 0, "SEND"]
# these are the events' IDs sent to a function when you click a button.
# the OPTIONS_ID is in the same order of OPTIONS.
OPTIONS_ID = [-31984,-31983,-31982,-31981,-31980,-31979, -31978, -31977, -31976, -31975, -31974, -31973, -31985] # the built in wxpython IDs for the buttons
GAME_POSITION = (400, 100)
GAME_SIZE = [900, 600]
def RandomNum():
count = 5
while count > 4:
num = randint(1000, 9999)
digits = str(num)
count = 0
for digit in digits:
for digit2 in digits:
if digit == digit2:
count = count + 1
return digits
class Frame(wx.Frame): # class for all the frames in our game.
def __init__(self, parent, id, title, pos, size):
wx.Frame.__init__(self, parent, id, title, pos, size)
self.panel = wx.Panel(self)
self.fdf = wx.TextCtrl(self.panel, size=(275, 75), pos=(520, 20))
self.count = 0
self.turnsCounter = 0
self.numbers = RandomNum()
self.bulls = 0
self.cows = 0
self.counter_of_turns = 0
self.check = False
self.grid = gridlib.Grid(self.panel, pos = (85, 150), size=(323, 212))
self.grid.CreateGrid(10, 3)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.panel, 1, wx.EXPAND)
sizer.Add(self.grid, 1, wx.EXPAND)
self.panel.SetSizer(sizer)
for i in range(10):
for j in range(4):
self.grid.SetReadOnly(i, j)
self.grid.SetColLabelValue(0, "guess")
self.grid.SetColLabelValue(1, "cows")
self.grid.SetColLabelValue(2, "bulls")
def message_dialog(self, message, caption, style=wx.YES_NO, position=GAME_POSITION):
if message != "": # making sure not to execute a message if its empety
message = wx.MessageDialog(None, message, caption, style, position)
answer = message.ShowModal()
if answer == wx.ID_YES:
self.reset()
else:
self.Destroy()
else:
return -1
# this function creates a textbox at a specific position with a specific size.
def write(self, panel, txt, pos, size=20, font_family=wx.SWISS, font_style = wx.NORMAL,font_weight = wx.BOLD, underline = False, color=wx.WHITE):
# create a textbox at a specific position with a specific size.
your_txt = wx.StaticText(panel, -1, txt, pos)
your_txt.SetFont(wx.Font(size,font_family,font_style,font_weight,underline))
your_txt.SetForegroundColour(color)
# same as above, just for a button.
def create_button(self, panel, txt, position, width, height, color, disable):
Size = wx.Size(width, height)
self.button = wx.Button(panel, -1, txt, position, Size)
self.button.SetBackgroundColour(color)
self.border = wx.BoxSizer(wx.VERTICAL)
self.border.Add(self.button)
self.Bind(wx.EVT_BUTTON, lambda evt: self.OnButton(evt), self.button)
if disable == True:
self.button.Disable()
def count_bulls(self, txtctrl, seria):
for i in range(4):
if seria[i] == txtctrl[i]:
self.bulls += 1
replacement = self.bulls
self.bulls = 0
return replacement
def count_cows(self, txtctrl, seria):
for i in range(4):
if seria[i] != txtctrl[i] and seria[i] in txtctrl:
self.cows += 1
replacement = self.cows
self.cows = 0
return replacement
def reset(self):
self.fdf.Clear()
self.grid.ClearGrid()
self.count = 0
self.turnsCounter = 0
self.numbers = RandomNum()
self.bulls = 0
self.cows = 0
self.counter_of_turns = 0
self.check = False
for child in self.panel.GetChildren():
if child.GetLabel() != "SEND":
child.Enable()
else:
child.Disable()
if self.count == 0:
if child.GetLabel() == "DEL" or child.GetLabel() == "0":
child.Disable()
def OnButton(self, event):
print repr(event.Id) + ","
print self.numbers
if event.Id in OPTIONS_ID: # if indeed an option button was pressed
exited = -1 # exited is 5100 if the user exited his dialog box
# assigning the events to the button.
for i in range(13):
if event.Id != -31985 and event.Id != -31975 and event.Id != -31974 and event.Id != -31973 and event.Id == OPTIONS_ID[i]:
self.fdf.AppendText(str(OPTIONS[i]))
self.count += 1
if event.Id == -31974:
self.fdf.AppendText(str(OPTIONS[10]))
self.count += 1
if event.Id == -31985:
self.reset()
if event.Id == -31973:
self.counter_of_turns += 1
print self.numbers
print self.fdf.GetValue()
cows = self.count_cows(self.fdf.GetValue(), self.numbers)
bulls = self.count_bulls(self.fdf.GetValue(), self.numbers)
self.grid.SetCellValue(self.turnsCounter,0, self.fdf.GetValue())
self.grid.SetCellValue(self.turnsCounter, 1, str(cows))
self.grid.SetCellValue(self.turnsCounter, 2, str(bulls))
self.fdf.Clear()
self.count = 0
if self.turnsCounter < 9:
self.turnsCounter += 1
if bulls == 4:
self.check = True
winsound.PlaySound('The_Power_-_Snap_1_.wav', winsound.SND_ASYNC | winsound.SND_LOOP)
self.message_dialog("Well done! you won this game..\n You won the game in %s turns .. \n Play again ? " % self.counter_of_turns , "You won!")
winsound.PlaySound(None, 0)
if event.Id == -31975:
if self.count > 0:
self.count -= 1
self.fdf.Remove(self.fdf.GetLastPosition()-1, self.fdf.GetLastPosition())
if self.count == 4:
for child in self.panel.GetChildren():
if isinstance(child, wx.Button):
try:
int(child.GetLabel())
except ValueError:
if child.GetLabel() == "SEND":
child.Enable()
else:
child.Disable()
elif self.check == False:
for child in self.panel.GetChildren():
if child.GetLabel() != "SEND":
child.Enable()
else:
child.Disable()
if self.count == 0:
if child.GetLabel() == "DEL" or child.GetLabel() == "0":
child.Disable()
#for child in self.panel.GetChildren():
#if isinstance(child, wx.Button):
#if child.GetLabel() in self.fdf.GetValue():
#child.Disable()
if self.counter_of_turns == 10 and self.check == False:
self.message_dialog("YOU LOST :( \n THE NUMBERS WERE %s \n PLAY AGAIN ?" % self.numbers,"Bad news ..")
class Game(wx.App):
def OnInit(self): # upon game opening
# I would like the options window to be the first window's parent
# so I will first set up our options window:
window = Frame(None, -1, "Good Luck!", GAME_POSITION, GAME_SIZE)
first_panel = window.panel
window.SetBackgroundColour(wx.BLACK)
window.write(first_panel, "BULLS AND COWS!", (50, 50), size=(35))
countX = 500
countY = 100
window.create_button(first_panel,"restart!", (50, 400), 100, 100, wx.WHITE, False)
for option in OPTIONS:
if str(option) == "SEND" or str(option) == "DEL":
window.create_button(first_panel,str(option), (countX, countY), 100, 100, wx.GREEN, True)
elif str(option) == "0":
window.create_button(first_panel,str(option), (countX, countY), 100, 100, wx.WHITE, True)
else:
window.create_button(first_panel,str(option), (countX, countY), 100, 100, wx.WHITE, False)
countX += 110
if str(option) == "3" or str(option) == "6" or str(option) == "9":
countY += 110
countX = 500
window.Show(True)
return True
def main():
MasterMind = Game()
MasterMind.MainLoop()
if __name__ == '__main__':
main()
PLEASE NOTE:
I upgraded my windows to windows 10 few days ego, it means that it doesn't work since the upgrade if it means something. (sorry if the grammer of my english not so well, it is not my native language..).
In my computer works fine (Python 2.7.11 and windows 7). If you import this class in another file, make sure if you call the main function.

Resources