I am trying to learn about loops and conditions. Therefore I coded a generator, which randomly create lotto/lottery numbers. However I created a global variable 'valCount', which stores the generation count. But still got this error:
Bitte die Anzahl zu erzeugender Lottoscheine angeben: 2
Input is an integer number. Number = 2
Traceback (most recent call last):
File "/Volumes/HDD/Users/Stephan/PycharmProjects/LottZahlenGeneratorLoop/main.py", line 87, in
check_user_input(userCountInput)
File "/Volumes/HDD/Users/Stephan/PycharmProjects/LottZahlenGeneratorLoop/main.py", line 70, in check_user_input
outPutCount()
File "/Volumes/HDD/Users/Stephan/PycharmProjects/LottZahlenGeneratorLoop/main.py", line 55, in outPutCount
for x in range(valCount):
NameError: name 'valCount' is not defined
Correct behaviour:
User needs to input a number. This number get validated, if it is a digit or a letter. If this is a digit, the lotto/lottery numbers should be created by the count of users input. Otherwise, user is asked to enter number.
My code:
# IMPORTS
import random
from datetime import datetime
import os
# CLEAR CONSOLE
def clearConsole():
command = 'clear'
if os.name in ('nt', 'dos'): # If Machine is running on Windows, use cls
command = 'cls'
os.system(command)
# VARIABLES
date = datetime.now()
dateFormat = str(date.strftime("%d-%m-%Y %H:%M:%S"))
mainNumbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50]
superNumbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
mainNumbersLotto = mainNumbers
del mainNumbersLotto[49] # löscht die 49. Stelle von mainnumbers, da Lotto 6aus49 nur Zahlen von 1-49 existieren
global valCount
# countToCreate = input("Bitte geben sie die Anzahl zum generieren an.")
# FUNCTION EUROJACKPOT GENERATOR
def eurojackpotFunc():
global eurojackpotOutput
RandomMainNumbers = str(sorted(random.sample(mainNumbers, 5)))
RandomSuperNumbers = str(sorted(random.sample(superNumbers, 2)))
eurojackpotOutput = "\nEurojackpot\n5 aus 50: " + RandomMainNumbers + "\nEurozahlen: " + RandomSuperNumbers
print(eurojackpotOutput)
# FUNCTION Lotto6aus49 GENERATOR
def lottoNumbersFunc():
global lottoNumbersOutput
RandomLottoNumber = str(sorted(random.sample(mainNumbersLotto, 6)))
lottoNumbersOutput = "\nLotto6aus49\n6 aus 49: " + RandomLottoNumber
print(lottoNumbersOutput)
# FUNCTION GENERATE TEXTFILE WITH RESULT
def generateTxtFile():
f = open("Lottozahle" + "- " + dateFormat + ".txt", "+w")
f.write(eurojackpotOutput + "\n " + lottoNumbersOutput)
def check_user_input(input):
try:
# Convert it into integer
valCount = int(input)
print("Input is an integer number. Number = ", valCount)
outPutCount()
except ValueError:
try:
# Convert it into float
valCount = float(input)
print("Input is a float number. Number = ", valCount)
userCountInputFunc()
except ValueError:
print("No.. input is not a number. It's a string")
userCountInputFunc()
def userCountInputFunc():
global userCountInput
userCountInput = input("Bitte die Anzahl zu erzeugender Lottoscheine angeben: ")
#
def outPutCount():
# LOOP FOR GENERATING COUNT
global valCount
xCount = 0
for x in range(valCount):
xCount = xCount + 1
print("\n#################")
print(xCount, ". Generation")
eurojackpotFunc()
lottoNumbersFunc()
generateTxtFile()
valCount = str(valCount)
print("\nEs wurden erfolgreich " + valCount + " Lottoscheine generiert.")
userCountInputFunc()
check_user_input(userCountInput)
The error message shows NameError: name 'valCount' is not defined (within your loop), and from the looks of it, you're attempting to define it twice– within outPutCount and in the true global scope. As an aside, no matter where you use the keyword global, it will always belong to the global scope.
Anyways, this is the problem with global variables (especially ones that have no value assigned to them before run-time)– figuring out their value while letting various areas in the code mutate them is a self-induced headache worth avoiding.
Try passing the value you want into the function by way of its arguments. You can implement this entire program without the usage of a global variable.
Hope that helps, and keep learning!
Related
I have inherited a set of Excel macros that take information from a spreadsheet and utilize Sendkeys to paste the information into our AP software. I have been debugging various issues mostly related to the timing of key-presses and the sequence they're entered. One issue that I have been unable to find a complete workaround for is converting characters such as % and ( ) into a paste-able format to be passed into our AP software. I have found various pieces online that explain using the CHR() function or regex. I have been unable to implement any of these answers into my application. These characters typically only affect our description line the current means of pasting the description passes through the following sections.
This captures the information where the description information is located and performs some very basic cleaning.
JEDescription = (Trim$(Range(cellDescription).Value))
JEDescription = Application.Substitute(JEDescription, "(", " ")
JEDescription = Application.Substitute(JEDescription, ")", " ")
That is passed into our "write_description" which determines which of our descriptions is used, it can either be a line by line description or a blanket description for a batch.
Private Sub write_Description(arrDetailJE() As DetailJE, i As Integer)
If TF_JE_Line_Description = True Then
SendKeys arrDetailJE(i).JE_Line_Description, True
Sleep lngSleep
Else
SendKeys JEDescription, True
Sleep lngSleep
End If
End Sub
I need a way to pass special values, most importantly % and ( ) through to the external program, via sendkeys. I found a UDF that works in theory but have been unable to implement it into my current macro.
Function CleanTrim(ByVal S As String, Optional ConvertNonBreakingSpace As Boolean = True) As String
Dim X As Long, CodesToClean As Variant
CodesToClean = Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, _
21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 127, 129, 141, 143, 144, 157)
If ConvertNonBreakingSpace Then S = Replace(S, Chr(160), " ")
For X = LBound(CodesToClean) To UBound(CodesToClean)
If InStr(S, Chr(CodesToClean(X))) Then S = Replace(S, Chr(CodesToClean(X)), "")
Next
' ""& added to preserve leading 0's in text fields
CleanTrim = ""&WorksheetFunction.Trim(S)
End Function
Something similar that allows the macro to detect keys that would interrupt Sendkeys and pass them through is the desired outcome.
I'm 63 and just started with Python (My first steps with Udemy).
I'm Croatian so this is croatian language in program but you will understand when you run a program. I know it can be cleaner, shorter, more elegant etc, but as I mentioned before - I'm beginner.
import random
jedan = random.sample(range(1,99),15)
dva = random.sample(range(1,99),15)
def raspaljot(jedan, dva, i):
for x in jedan:
for y in dva:
if y == x:
index1 = jedan.index(x)
index1_str = str(index1)
index2 = dva.index(y)
index2_str = str(index2)
i += 1
x = str(x)
print(" Broj \033[31m" + x + "\033[0m,je dupli i nalazi se u listi jedan: na poziciji: \033[34m"
+ index1_str + "\033[0m a u listi dva na poziciji: \033[35m"+ index2_str + "\033[0m")
print()
print(jedan)
print(dva)
if i != 0:
print("\n *** Ukupno ima ", i, 'duplih brojeva. ***')
elif i == 0:
print("Nema duplih brojeva. :) ")
i = 0
raspaljot(jedan, dva,i)
What program do is finding duplicates in 2 random lists, them print duplicates in color and detecting position inside list[1] and list[2].
What I trying to do is printing list1 and list2 but showing duplicates in color.
For example:
[14, 78, 85, 31, 5, 54, 13, 46, 83, 4, 35, 41, 52, 51, 32]
[72, 40, 67, 85, 54, 76, 77, 39, 51, 36, 91, 70, 71, 38, 55]
here we have 3 duplicates (85,54,51). This above example on the console End was printed in white color, but I wanna these 3 numbers in red color in those two lines above.
Is this possible? I couldn't find a solution.
PS. Wing Pro version 7 on Fedora 33 Workstation / In WIngIde colors are only displayed in an external console and not the Debug I/O tool. :)
Simple solution would be something like this:
# Change list to string
jedan_str = str(jedan)
# Create set with numbers that need new color
num_set = {"85", "54", "51"}
# Iterate over every number and wrap it with color change
for i in num_set:
# Note that I used f-string to format string
# But you can also do this as "\033[31m" + i + "\033[0m"
jedan_str = jedan_str.replace("85", f"\033[31m{i}\033[0m")
# Print string that represent list
print(jedan_str)
Following the idea of using a set to determine which elements are in both lists (as Cv4niak proposed in his answer), I created a function to print the output as you desire. There are numerous other ways of achieving it, but I think this is a simple yet effective way.
The idea is to use the cprint() function from the termcolor package. You can install it with pip install termcolor, and then print normally all elements, except the ones that are duplicates, which will be printed using cprint(item, "red").
The "{:0>2d}" formatting in each ìtem print serves only to pad the number with zeros (so 2 will be printed as 02, for example), in order for the output of both lists to be aligned.
import random
from termcolor import cprint
def mark_duplicates(first, second):
duplicates = list(set(first).intersection(second))
if duplicates:
for list_ in [first, second]:
print("[", end="")
for item in list_:
if item in duplicates:
cprint("{:0>2d}".format(item), "red", end=",")
else:
print("{:0>2d}".format(item), end=",")
print("\b]")
else:
print("No duplicates.")
jedan = random.sample(range(1, 99), 15)
dva = random.sample(range(1, 99), 15)
mark_duplicates(jedan, dva)
With this, if there are no duplicates, the No duplicates. string will be printed. Also you can change the color with not much effort, and use other nice functionalities from termcolor package.
I'm learning to use backtrader and I've come across a problem when trying to print out the datafeed. It correctly prints the day, open, high, low, close and volume but the hour and minutes data seems to default to 23:59:59.999989 on every line.
Here is a sample of the data source:
datetime,open,high,low,close,volume,,
11/2/2020 9:30,330.187,330.188,329.947,330.038,4.79,,
11/2/2020 9:31,330.038,330.438,329.538,329.677,5.49,,
11/2/2020 9:32,329.667,330.248,329.577,330.117,5.8,,
11/2/2020 9:33,330.128,330.328,329.847,329.948,5.59,,
11/2/2020 9:34,329.967,330.308,329.647,329.698,6.24,,
and the code I use to add the data to backtrader is:
data = bt.feeds.GenericCSVData(
dataname = 'SPY_11_2020_1M.txt',
name= 'SPY',
datetime = 0,
dtformat = ('%m/%d/%Y %H:%M'),
period = bt.TimeFrame.Ticks,
compression = 1,
fromdate = params['fromdate'],
todate = params['todate'],
open = 1,
high = 2,
low = 3,
close = 4,
volume = 5,
openinterest = -1,
)
cerebro.adddata(data)
my code for the trategy, which is a simple buy and hold strategy, is:
import backtrader as bt
from datetime import datetime as dt
class BuyHold(bt.Strategy):
def __init__(self):
# self.time = self.datas[0].datetime.datetime(0),
self.open = self.datas[0].open
self.high = self.datas[0].high
self.low = self.datas[0].low
self.close = self.datas[0].close
self.volume = self.datas[0].volume
def next(self):
print('{0} {1}\t{2}\t{3}\t{4}\t{5}\t{6}'.format(
self.datas[0].datetime.date(0),
self.datas[0].datetime.time(0),
self.open[0],
self.high[0],
self.low[0],
self.close[0],
self.volume[0]
))
# print('{0}\t{1}\t{2}\t{3}\t{4}\t{5}'.format(
# self.time,
# self.open[0],
# self.high[0],
# self.low[0],
# self.close[0],
# self.volume[0]
# ))
if self.position.size == 0:
size = int(self.broker.getcash() / self.data)
self.buy(size = size)
The printout I get is as:
2020-11-02 23:59:59.999989 330.187 330.188 329.947 330.038 4.79
2020-11-02 23:59:59.999989 330.038 330.438 329.538 329.677 5.49
2020-11-02 23:59:59.999989 329.667 330.248 329.577 330.117 5.8
2020-11-02 23:59:59.999989 330.128 330.328 329.847 329.948 5.59
2020-11-02 23:59:59.999989 329.967 330.308 329.647 329.698 6.24
I also tried it with the commented out self.time with the commented out print line which provides similar result in a slightly different format as:
(datetime.datetime(2020, 11, 2, 23, 59, 59, 999989),) 330.187 330.188 329.947 330.038 4.79
(datetime.datetime(2020, 11, 2, 23, 59, 59, 999989),) 330.038 330.438 329.538 329.677 5.49
(datetime.datetime(2020, 11, 2, 23, 59, 59, 999989),) 329.667 330.248 329.577 330.117 5.8
(datetime.datetime(2020, 11, 2, 23, 59, 59, 999989),) 330.128 330.328 329.847 329.948 5.59
(datetime.datetime(2020, 11, 2, 23, 59, 59, 999989),) 329.967 330.308 329.647 329.698 6.24
(datetime.datetime(2020, 11, 2, 23, 59, 59, 999989),) 329.698 330.198 329.568 329.948 6.51
I don't know what I'm missing here.
struggle with the problem some days,i use isoformat to read the time and date
strategy
class my_strategy1(bt.Strategy):
def log(self, txt, dt=None):
''' Logging function for this strategy'''
# dt = dt or self.datas[0].datetime.date(0)
#the fellowing will print date ,that is,2021-08-06
print(self.datas[0].datetime.date(0).isoformat())
#the fellowing will print time,that is,08:09:01
print(self.datas[0].datetime.time(0).isoformat())
print(txt)
def __int__(self):
pass
def next(self):
self.log('Close, %.2f' % self.dataclose[0])
print("trend is", self.datas[0].lines.trend[0])
pass
data class
class My_CSVData(bt.feeds.GenericCSVData):
"""
如何添加格外的数据列在excel中进行处理
how to append the other data to csv
"""
lines = ('trend',)
params = (
('trend', -1),
)
def get_data_via_excel(path):
datatest=My_CSVData(
dataname=path,
timeframe=bt.TimeFrame.Minutes,
compression=60,
dtformat='%Y-%m-%d %H:%M:%S',
tmformat = '%H:%M:%S',
fromdate = datetime(2021,4,16),
todate = datetime(2021,7,30),
datetime = 0,
high=2,
open =1,
close=4,
low =3,
volume=5,
openinterest =6,
trend = 7 ,#not use -1
)
return datatest
data source
datetime,open,high,low,close,volume,openinterest,trend
2021-04-16 09:59:00,5138,5144,5109,5117,200,0,-2
2021-04-16 11:00:00,5117,5122,5089,5102,200,0,-2
2021-04-16 11:29:00,5103,5118,5096,5105,200,0,-1
2021-04-16 14:00:00,5105,5152,5105,5142,200,0,0
2021-04-16 15:00:00,5141,5142,5111,5116,200,0,1
2021-04-16 21:59:00,5122,5141,5116,5129,200,0,0
2021-04-16 23:00:00,5128,5136,5108,5120,200,0,0
This problem also took me few hours. And I find the solution from another web.
Here.
For minute data tell cerebro that you are using minute data (timeframe) and how many minutes per bar (compression).
data = bt.feeds.GenericCSVData(
dataname = 'SPY_11_2020_1M.txt',
name= 'SPY',
datetime = 0,
dtformat = ('%m/%d/%Y %H:%M'),
**timeframe=bt.TimeFrame.Minutes,**
period = bt.TimeFrame.Ticks,
compression = 1,
fromdate = params['fromdate'],
todate = params['todate'],
open = 1,
high = 2,
low = 3,
close = 4,
volume = 5,
openinterest = -1,
)
My function is as below. I am taking input of 2 nos, finding random nos between them and then multiplying them all.
start = int(input("Enter start value"))
end = int(input("Enter end value"))
import random
numlist = random.sample(range(start,end),10)
print("list of random nos are" + str(numlist))
from functools import reduce
prod = reduce(lambda x,y: x*y, numlist)
print("the product of random nos: {0} is {1}".format(numlist,prod))
The output is as below
Enter start value7
Enter end value89
list of random nos are: [58, 13, 47, 43, 44, 56, 86, 14, 25, 71]
the product of random nos: [51, 30, 7, 25, 49, 29, 35, 54, 27, 67] is 1300840136977500
My question is a) why does the list of random nos change (first line [58,13..second line [51,30...) even though i haven't run this numlist = random.sample(range(start,end),10) line of code again.
What is happening here ?
i just added print(numlist) and the random numbers are not changing for me.Try this instead
end = int(input("Enter end value"))
import random
numlist = random.sample(range(start,end),10)
print(numlist)
from functools import reduce
prod = reduce(lambda x,y: x*y, numlist)
print("the product of random nos: {0} is {1}".format(numlist,prod))
Use a function so that the random value is regenerated each time the function is called.
>>> f = random.random()
>>> f
0.27924394986694034
>>> def randomizer(): return random.random()
...
>>> randomizer()
0.10425940372082476
>>> randomizer()
0.5703202999521394```
I'm a newbie in python , so I was creating this project to create Sudoku using brute force method. To some extent I was successful but I am not able to figure out why sometimes the program hangs randomly while generating. Hope someone can pinpoint the issue.
I have tried debugging the code but still am not able to pinpoint what's causing the issue. The most close I have come to figuring something about the bug is that it is caused somewhere in the brute_generator() function.
A little Info on how the code is intended to work :-
The Sudoku is generated row by row by calling the brute_generator()function 9 times.
In the function brute_generator() the rows are generated using trial and error where a random number is picked up from possibilities list which is from number 1-9 and then it is treated as first number of row , now check_1() and check_2() function are called to check if the number has already been repeated in its column in previous rows if any and its 3x3 square as per the rules of Sudoku , if yes then the number is added to blacklist list and another number is chosen till the right number is obtained. When the right number is obtained it is appended to a temp_array while being removed from possibilities list so that it cannot be chosen again and counter is increased by 1 . This repeats till the row is generated (i.e counter = 9) or no number from possibilities list can be placed in a given cell of row (i.e len(blacklist)==len(possibilities) , all possibilities are blacklisted) in which case the row being generated is scraped by returning all variables to their default values and a new row is generated . This happens until the perfect row is obtained which is then appended to sudoku_array()
def check_1(x , temp_array , sudoku_array) : # Check for recurrence in the Block in which the cell exist
flag_1 = True
if len(temp_array) < 3 :
j = 2
l = 0
elif len(temp_array) < 6 :
j = 5
l = 3
else :
j = 8
l = 6
i = len(sudoku_array)
if len(sudoku_array) < 3 :
o = 0
elif len(sudoku_array) < 6 :
o = 3
else :
o = 6
for m in range(o,i) :
for n in range(l,j+1) :
if x == sudoku_array[m][n] :
flag_1 = False
break
if x == sudoku_array[m][n] :
break
return flag_1
def check_2(x, counter, sudoku_array) : # Check for the recurrence of number in its consequent column
flag_2 = True
for k in range(len(sudoku_array)) :
if x == sudoku_array[k][counter] :
flag_2 = False
break
return flag_2
def brute_generator(sudoku_array) : # The main sudoku Generating Algo.
all_possibilities = [1,2,3,4,5,6,7,8,9]
possibilities = all_possibilities.copy()
blacklist = []
counter = 0
temp_array = []
while counter != 9 :
if len(blacklist) == len(possibilities) :
all_possibilities = [1,2,3,4,5,6,7,8,9]
possibilities = all_possibilities.copy()
blacklist = []
counter = 0
temp_array = []
continue
x = random.choice(possibilities)
if x not in blacklist :
if len(sudoku_array) != 0 :
if check_1(x, temp_array , sudoku_array) == False :
blacklist.append(x)
continue
elif check_2(x, counter , sudoku_array) == False :
blacklist.append(x)
continue
possibilities.remove(x)
counter+=1
temp_array.append(x)
blacklist = []
sudoku_array.append(temp_array)
sudoku_array = [] # This will be the generated sudoku
for i in range(9) :
brute_generator(sudoku_array)
The Traceback calls show the following after the program is stuck
Traceback (most recent call last):
File "c:\program files (x86)\microsoft visual studio\2017\community\common7\ide\extensions\microsoft\python\core\ptvsd_launcher.py", line 119, in <module>
vspd.debug(filename, port_num, debug_id, debug_options, run_as)
File "c:\program files (x86)\microsoft visual studio\2017\community\common7\ide\extensions\microsoft\python\core\Packages\ptvsd\debugger.py", line 37, in debug
run(address, filename, *args, **kwargs)
File "c:\program files (x86)\microsoft visual studio\2017\community\common7\ide\extensions\microsoft\python\core\Packages\ptvsd\_local.py", line 64, in run_file
run(argv, addr, **kwargs)
File "c:\program files (x86)\microsoft visual studio\2017\community\common7\ide\extensions\microsoft\python\core\Packages\ptvsd\_local.py", line 125, in _run
_pydevd.main()
File "c:\program files (x86)\microsoft visual studio\2017\community\common7\ide\extensions\microsoft\python\core\Packages\ptvsd\_vendored\pydevd\pydevd.py", line 1752, in main
globals = debugger.run(setup['file'], None, None, is_module)
File "c:\program files (x86)\microsoft visual studio\2017\community\common7\ide\extensions\microsoft\python\core\Packages\ptvsd\_vendored\pydevd\pydevd.py", line 1099, in run
return self._exec(is_module, entry_point_fn, module_name, file, globals, locals)
File "c:\program files (x86)\microsoft visual studio\2017\community\common7\ide\extensions\microsoft\python\core\Packages\ptvsd\_vendored\pydevd\pydevd.py", line 1106, in _exec
pydev_imports.execfile(file, globals, locals) # execute the script
File "c:\program files (x86)\microsoft visual studio\2017\community\common7\ide\extensions\microsoft\python\core\Packages\ptvsd\_vendored\pydevd\_pydev_imps\_pydev_execfile.py", line 25, in execfile
exec(compile(contents+"\n", file, 'exec'), glob, loc)
File "C:\Users\groot\source\repos\PythonApplication5\PythonApplication5\PythonApplication5.py", line 145, in <module>
brute_generator(sudoku_array)
File "C:\Users\groot\source\repos\PythonApplication5\PythonApplication5\PythonApplication5.py", line 109, in brute_generator
x = random.choice(possibilities)
File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\lib\random.py", line 255, in choice
def choice(self, seq):
File "c:\program files (x86)\microsoft visual studio\2017\community\common7\ide\extensions\microsoft\python\core\Packages\ptvsd\_vendored\pydevd\_pydevd_bundle\pydevd_trace_dispatch_regular.py", line 273, in __call__
frame_cache_key = (frame.f_code.co_firstlineno, frame.f_code.co_name, frame.f_code.co_filename)
KeyboardInterrupt
Hope someone can pinpoint the issue.
The issue is that for i in range(9) : brute_generator(sudoku_array) can create a partial sudoku_array which is impossible to complete, e. g. the five rows:
[1, 5, 7, 2, 3, 6, 8, 4, 9],
[9, 8, 2, 5, 4, 7, 6, 3, 1],
[4, 3, 6, 8, 1, 9, 7, 2, 5],
[5, 7, 9, 4, 2, 1, 3, 6, 8],
[6, 1, 3, 9, 5, 8, 2, 7, 4]
Now the function keeps searching for an appropriate sixth row which it never finds, and it never backtracks, which would mean throwing away previously generated rows to get out of the dead end.