I am trying to create a class called "Binary" and the main idea of it is to take a string representing a fixed width binary number that is 16 bits as it's only parameter and store it as a numpy integer array into it's one instance variable "bit_array".
If the given string is greater than 16 characters or contains anything other than 0's and 1's, it is to raise a RuntimeError. If "string" is less than 16 characters, it is to pad on the leftmost digit of given string onto the start of the numpy array until the resulting array contains exactly 16 digits. The given string defaults to '0' and accepts an empty string, treating an empty string as '0'. The code I have written for init is as follows (in "hw4.py" - the main file for this assignment):
import numpy as np
class Binary:
def __init__(self, string='0'):
if not string:
string = '0'
else:
if len(string) > 16:
raise RuntimeError
else:
for i in string:
if i != '1' and i != '0':
raise RuntimeError
if len(string) == 16:
int_arr = np.array(tuple(string))
self.bit_array = int_arr
else:
int_arr_inc = np.array(tuple(string))
if int_arr_inc[0] == 0:
pad = np.zeros((16 - len(int_arr_inc)), int)
else:
pad = np.ones((16 - len(int_arr_inc)), int)
self.bit_array = np.concatenate((pad, int_arr_inc))
There is also an eq overloaded method intended to compare the bit_array of another "Binary" object in this class (this passes the spec's test case so there shouldn't be any changes required here, just more for being transparent):
def __eq__(self, other):
if str(self.bit_array) == str(other.bit_array):
return True
else:
return False
The spec requires that there is no use of list() or any form of lists at all in the init method. The method is not to return anything and it's only purpose is to build a Binary object that has a bit_array that converts the string parameter into a numpy integer array. The test cases I have to test against calls the following test case (in a test file "hw4_test.py"):
from hw4 import Binary
import unittest, numpy as np
class TestBinary(unittest.TestCase):
def setUp(self):
self.bin_0 = Binary("")
self.bin_1 = Binary("01")
self.bin_2 = Binary("010")
def test_init(self):
self.assertTrue(all(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) == self.bin_0.bit_array))
self.assertTrue(all(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]) == self.bin_1.bit_array))
self.assertTrue(all(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]) == self.bin_2.bit_array))
However, the first test case here fails, giving me :
Traceback (most recent call last):
File "C:\Users\17606\Desktop\ISTA-350\hw4\hw4_test.py", line 30, in test_init
self.assertTrue(all(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) == self.bin_0.bit_array))
TypeError: 'bool' object is not iterable
I've tried many ways of creating the numpy arrays, such as fromstring (which is deprecated anyways) and trying with a map of the parameter string, to no avail. As the test case code above shows, I am expecting
Binary("")
To result in a Binary object containing a bit_array of a numpy array like
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
But the TypeError above keeps occuring. Any ideas? I am having trouble understanding where I am even iterating over anything that could be a bool type. I am using Python 3.10 on Windows 10 with PyCharm as my IDE.
P.S
This is for a school course and I am not very concerned about conventions or efficiency for this. Just syntax and logic :)
Thanks!
I want to use dateparser to detect which cell contains a date. I have a broad range of different date formats: Fr, 21.02.2020 // 20.02.2020 // 21.02 // 21-02-2020 // January, 21 2020 // 21-Jan-2020 // 21/02/20 and I am sure there will still come a couple more in the future. The library dateparser is able to detect all of them pretty well, though it also detects 'PO', 'to','06','16:00' as date or relative date, which I don't want. I tried to check the Documentation and turn the relative date off or to look how to change to only detect "real dates". In the settings they offer different PARSERS and the possibility to only use some of them. These are the default PARSERS and the program runs through all of them:
'timestamp': If the input string starts with 10 digits, optionally followed by additional digits or a period (.), those first 10 digits are interpreted as Unix time.
'relative-time': Parses dates and times expressed in relation to the current date and time (e.g. “1 day ago”, “in 2 weeks”).
'custom-formats': Parses dates that match one of the date formats in the list of the date_formats parameter of dateparser.parse() or DateDataParser.get_date_data.
'absolute-time': Parses dates and times expressed in absolute form (e.g. “May 4th”, “1991-05-17”). It takes into account settings such as DATE_ORDER or PREFER_LOCALE_DATE_ORDER.
'base-formats': Parses dates that match one of the following date formats
I tried to only use one of them with the part settings={'base-formats':True}) in my code, nonetheless it won't work. Furthermore they offer the following snippet to turn of individual PARSERS:
>>> from dateparser.settings import default_parsers
>>> parsers = [parser for parser in default_parsers if parser != 'relative-time']
>>> parse('today', settings={'PARSERS': parsers})
Here pops up the error:
ModuleNotFoundError: No module named 'dateparser.settings'
I tried pip install, won't work.
Link to docu: https://dateparser.readthedocs.io/en/latest/#settings
And here's my code:
import dateparser
inputlist = [[' ','Supplier:',' Company Y', ' ', 'Project:','Carasco', ' '],[' ','21-Jan-2020',' ','Consultant:','James Farewell', ' ', ' '],['PO', ' Service', ' Cost Center', ' Accounting Object', ' deliver at', ' Amount', ' Unit'],['0106776','XYZ', 'Countable',' ', '16:00','6,00','h',],['Fr, 21.02.2020', '20.03.2020', ' ', ' ', ' ', ' ','6/04/20']]
print(inputlist)
outerlist=[]
for row in inputlist:
innerlist = []
for cell in row:
parsecheck = dateparser.parse(cell, languages=['en', 'de'], settings={'base-formats':True})
if parsecheck == None:
innerlist.append(0)
else:
innerlist.append(1)
outerlist.append(innerlist)
print(outerlist)
I currently get:
[0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 1, 1, 1], [1, 1, 0, 0, 0, 0, 1]]
Desired Output:
[0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0,0, 0, 0], [1, 1, 0, 0, 0, 0, 1]]
This is the best I could do:
import dateparser
import locale
inputlist = [[' ','Supplier:',' Company Y', ' ', 'Project:','Carasco', ' '],[' ','21-Jan-2020',' ','Consultant:','James Farewell', ' ', ' '],['PO', ' Service', ' Cost Center', ' Accounting Object', ' deliver at', ' Amount', ' Unit'],['0106776','XYZ', 'Countable',' ', '16:00','6,00','h',],['Fr, 21.02.2020', '20.03.2020', ' ', ' ', ' ', ' ','6/04/20']]
print(inputlist)
customlist = ["%d.%m.%Y", "%d-%b-%Y", "%w/%m/%y", "%a, %d.%m.%Y"]
outerlist=[]
saved = locale.setlocale(locale.LC_ALL)
locale.setlocale(locale.LC_ALL, 'de_de')
for row in inputlist:
innerlist = []
for cell in row:
parsecheck = dateparser.parse(cell, languages=['en', 'de'], settings={'PARSERS':['custom-formats']}, date_formats=customlist)
if parsecheck == None:
innerlist.append(0)
else:
innerlist.append(1)
outerlist.append(innerlist)
locale.setlocale(locale.LC_ALL, saved)
print(outerlist)
The output is:
[[0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [1, 1, 0, 0, 0, 0, 1]]
For parsing Fr, 21.02.2020 I changed the locale to Germany and, near the end I go back to your initial locale.
The format was based on documentation of strftime() and strptime() Behavior
Agreed that changing the settings does not work as expected based on the docs. Looking at the code, it doesn't look like you can get date-only objects (though I'm not an expert and may have missed something). If I understand correctly, it should be settings = {'PARSER': 'base-formats'} instead of settings = {'base-formats':True}, but that doesn't solve your problem.
I can only suggest a work around making use of the fact that the hour and minute of the returned datetime object default to 0.
import dateparser
outerlist=[]
for row in inputlist:
innerlist = []
for cell in row:
parsecheck = None
if dateparser.parse(cell, settings={'STRICT_PARSING':True}) != None and dateparser.parse(cell).hour == 0:
parsecheck = dateparser.parse(cell, languages=['en', 'de'], settings={'PARSER':'date_formats'})
if parsecheck == None:
innerlist.append(0)
else:
innerlist.append(1)
outerlist.append(innerlist)
STRICT_PARSING:True means the returned value is None if any ofYEAR, DAY or MONTH are missing, which takes care of 'PO', 'h' and '6,00' returning valid datetime objects. Checking if the hour attribute is zero gets rid of the valid times.
Unfortunately
for cell in row:
parsecheck = dateparser.parse(cell, languages=['en','de'], settings={'STRICT_PARSING':True, 'PARSER':'date_formats'})
if parsecheck != None and parsecheck.hour == 0:
innerlist.append(1)
else:
innerlist.append(0)
doesn't seem to work since it interprets '16:00' as a date
edit - you don't need to import datetime
Please I need help with this code.I want mylist to retain values appended to it next time the function 'no_repeat_rule' is called. I'm pretty new to python. My code is below:
def no_repeat_rule(play_board):
mylist = list()
if seeds_left(play_board) == 2 and sum(play_board[:6])== 1:
mylist.append(play_board)
return mylist
Output of this code (in part) is:
...
[[1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]]
Player 1 chose cup 0
[[0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]]
Player 2 chose cup 6
[[0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]]
...
what I want the function 'no_repeat_rule' to do is to grow mylist each time a player plays. I don't know if this is clear enough to get help?
The simplest thing to do would be to add another parameter in the function defintion, such that it looks like:
def no_repeat_rule(play_board, aList):
Before you call the function, declare a list outside of the function. Set this equal to the result of the function, and pass it as a parameter whenever you call the function. For instance:
x = list()
def no_repeat_rule(play_board, aList):
myList = aList
if seeds_left(play_board) == 2 and sum(play_board[:6])== 1:
myList.append(play_board)
return myList
x = no_repeat_rule(someBoardHere, x)
I believe this should work if I understand what you're asking. If not, please respond and I'll try something else.
what do you need is an object which is associated with the function. It calls attribute. It is very handy in python.
Your code may look like this:
def no_repeat_rule(play_board):
if not hasattr(no_repeat_rule,"mylist"):
no_repeat_rule.mylist = []
if seeds_left(play_board) == 2 and sum(play_board[:6])== 1:
no_repeat_rule.mylist.append(play_board)
return no_repeat_rule.mylist
I couldn't check this code, but it should work for local atributes. BTW it is for python 2.7