-
Notifications
You must be signed in to change notification settings - Fork 89
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adagrams: Snow Leopards ( Kae & Diana) #66
base: master
Are you sure you want to change the base?
Changes from all commits
350753d
a6182d0
e7791b2
22c668d
1a544b0
f4b52a8
23647b0
4161970
64e8efd
b5a3713
1fbdf5f
62a8ef1
12e33fe
af537eb
ec8f1cd
e069ce4
6c37747
c2f1b4e
cc7a91d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,128 @@ | ||
def draw_letters(): | ||
pass | ||
def mystery(numbers): | ||
index = 0 | ||
while index < len(numbers): | ||
numbers[index] *= 2 | ||
index += 1 | ||
|
||
return numbers | ||
|
||
def uses_available_letters(word, letter_bank): | ||
pass | ||
nums = [1, 2, 3, 4, 5] | ||
mystery(nums) | ||
|
||
def score_word(word): | ||
pass | ||
print(nums[3]) | ||
|
||
def get_highest_word_score(word_list): | ||
pass | ||
|
||
|
||
|
||
|
||
|
||
# def get_fire_students(students): | ||
# ''' | ||
# INPUT: A list of dictionaries with the "name" and "class" key-value pairs. | ||
# Example: get_fire_students([{ "name": "Ada", "class": "fire"}, { "name": "Taylor", "class": "earth" }]) | ||
# RETURN VALUE: A list of dictionaries with **only** the students in the "fire" class. | ||
# ''' | ||
# temp = [] | ||
# students = students.copy() | ||
# | ||
# while students: | ||
# student = students.pop() | ||
# if student["class"] == "fire": | ||
# temp.append(student) | ||
# # | ||
# # while temp: | ||
# # students.append(temp.pop()) | ||
# print(students) | ||
# return students | ||
# | ||
# | ||
# get_fire_students([{ "name": "Ada", "class": "fire"}, { "name": "Taylor", "class": "earth" }]) | ||
|
||
cur_score = score_word(word) | ||
word_len = -len(word) | ||
has_10 = word_len == -10 # True if word length is 10. | ||
|
||
# def hamming_distance(strand1, strand2): | ||
# count_of_differences = 0 | ||
# index = 0 | ||
# | ||
# | ||
# if len(strand1) == 0 or len(strand2) == 0: | ||
# raise ValueError("One of your inputs is invalid, please try again.") | ||
# | ||
# | ||
# for letter in strand2: | ||
# # if letter[index] not in strand2[index]: | ||
# count_of_differences += 1 | ||
# index += 1 | ||
# | ||
# | ||
# return count_of_differences | ||
# | ||
# print(hamming_distance("GAGCCTACTAACGGGAT", "CATCGTAATGACGGCCT")) | ||
# print(hamming_distance("GAG", "GAG")) | ||
# print(hamming_distance("GAG", "")) | ||
|
||
|
||
# def score(word): | ||
# | ||
# point_system = { | ||
# ("A", "E", "I", "O", "U", "L", "N", "R", "S", "T"): 1, | ||
# ("D", "G"): 2, | ||
# ("B", "C", "M", "P"): 3, | ||
# ("F", "H", "V", "W", "Y"): 4, | ||
# "K": 5, | ||
# ("J", "X"): 8, | ||
# ("Q", "Z"): 10 | ||
# } | ||
# | ||
# total_score = 0 | ||
# | ||
# try: | ||
# word = word.upper() | ||
# except AttributeError as err: | ||
# return "You've entered a number, please enter a letter and try again." | ||
# except Exception: | ||
# print("You've entered a number, please enter a letter and try again.") | ||
# raise | ||
# | ||
# letters_of_word = list(word) | ||
# | ||
# if len(letters_of_word) == 0: | ||
# return None | ||
# | ||
# else: | ||
# for letter in letters_of_word: | ||
# for key,value in point_system.items(): | ||
# if letter in key: | ||
# total_score += value | ||
# return total_score | ||
# | ||
# | ||
# # print(score("Dog")) | ||
# # print(score(123)) | ||
# print(score("supercalifragilisticexpialidocious")) | ||
# print(score('')) | ||
|
||
|
||
# example input 1: "supercalifragilisticexpialidocious" | ||
# expected output 1: 56 | ||
|
||
# example input 2: "Français" | ||
# expected output 2: | ||
# | ||
# def test_ridiculous_words(): | ||
# # arrange | ||
# word = "supercalifragilisticexpialidocious" | ||
# # act | ||
# result = score(word) | ||
# # assert | ||
# assert result = 56 | ||
# | ||
# def test_letter_not_in_English(): | ||
# # arrange | ||
# word = "Français" | ||
# # act | ||
# result = score(word) | ||
# # assert | ||
# result = |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,11 @@ | ||
attrs==20.3.0 | ||
iniconfig==1.1.1 | ||
numpy==1.23.3 | ||
packaging==20.8 | ||
pluggy==0.13.1 | ||
py==1.10.0 | ||
pyparsing==2.4.7 | ||
pytest==7.1.1 | ||
scipy==1.9.1 | ||
toml==0.10.2 | ||
tomli==2.0.1 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,7 @@ | ||
import pytest | ||
from scipy import stats as stats | ||
from pprint import pprint | ||
from collections import Counter | ||
|
||
from adagrams.game import draw_letters | ||
|
||
|
@@ -65,3 +68,64 @@ def test_letter_not_selected_too_many_times(): | |
# Assert | ||
for letter in letters: | ||
assert letter_freq[letter] <= LETTER_POOL[letter] | ||
|
||
def test_chi_square_frequencies(): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I DO NOT have stats experience, so beyond being aware of the chi-square test sounding like the right thing to do, I can only say that your approach makes sense to me: tally up the observed letter counts over a "large" number of runs, and check whether the distribution looks like the expected distribution from the tile counts. The test that we supplied really just checks that no impossible hands can be drawn, and while it would be possible for that test to be "defeated" by a faulty implementation (i.e., the implementation might not be properly enforceing the limits, but for all of the 1000 test runs, it never happens to exceed any), it will never yield a false negative. It will never fail as long as the implementation is correct. Statistical based tests are a touchy subject. We want to be sure that unit tests NEVER have a chance of failing for working code. EVen worse if it fails sporadically. So any statistical test would need to be careful tuned to ensure that the tolerances are such that they would NEVER cause the test to fail. If there is a test that sporadically fails, that trains the programmers to ignore the test. If it fails, "it's just that test that fails sometimes," and that can mean that if it truly is failing, no one will take any notice. Code that depends on randomness does present a problem for testing. Another approach is to avoid the randomness entirely in the test. In our code, rather than directly relying on a library function that has randomness baked in (like randint or sample) we might have our code depend on a passed in supplier of randomness. In the real code, we can provide an implementation that uses the typical provider of randomness, but in the test, we might pass in a more deterministic provider that we know will always produce a particular result, turning the test from a check of statistical probability more towards a test of expected stable behavior. If we do still want to run some statistical tests (probably still a good idea), we might store them in a different suite of tests. There are more kinds of tests than just unit tests (short, small tests that we run frequently while developing to check basic behaviors), like integration testing, smoke testing, or fuzz testing. These aren't usually run by devs all the time, and hence, might provide a better situation for the test runner to spend more time looking into any failures without it becoming a blocker to the regular devlopment cycle. As it is, this test actually did fail for me once in the few times I ran it! 😱 |
||
|
||
# this *should* work | ||
# technique adapted from | ||
# http://practicalcryptography.com/cryptanalysis/text-characterisation/chi-squared-statistic/ | ||
# TODO: get someone with better stats experience to | ||
# double-check this | ||
|
||
# arrange/act | ||
|
||
|
||
# normalize LETTER_POOL frequencies | ||
pool_sum = sum(LETTER_POOL.values()) | ||
pool_freqs = {letter : (value / pool_sum) for letter,value in LETTER_POOL.items()} | ||
|
||
# collect our sample | ||
sample_counter = Counter() | ||
for i in range (500): | ||
letters = draw_letters() | ||
for letter in letters: | ||
sample_counter[letter] += 1 | ||
|
||
# ------------- | ||
# Test the test | ||
# ------------- | ||
# | ||
# Uncomment for big fail! | ||
|
||
# Add a bunch of extra "Q" tiles! | ||
# sample_counter['Q'] *= 2 | ||
|
||
# Take away some "E" tiles! | ||
# sample_counter['E'] /= 2 | ||
|
||
# organize our expected and sample | ||
# into parallel lists | ||
expected = [] | ||
sample = [] | ||
total = sample_counter.total() | ||
for letter, freq in pool_freqs.items(): | ||
expected.append(freq * total) | ||
sample.append(sample_counter[letter]) | ||
|
||
# pprint(sample) | ||
# pprint(expected) | ||
# pprint(sum(expected)) | ||
chi = stats.chisquare(sample, expected) | ||
pprint(chi.pvalue) | ||
|
||
# low is bad, high is good | ||
assert chi.pvalue > 0.05 | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice documentation of your collaboration plan.