Open Side Menu Go to the Top
Register
Programming homework and newbie help thread Programming homework and newbie help thread

02-12-2015 , 12:22 PM
Quote:
Originally Posted by CyberShark93
i think we require integer solutions to the congruence a^x = b (mod c)
taking log will give us the solution to a^x=b, however x is not necessarily an integer in that case
maybe I'm missing something but how's this? you're saying there is an integer solution but since logs are monotonically increasing I would think this is the only solution. I'm leveraging the fact that log of both sides is x log a = log(b%c), so x = log(b%c)/log a

Code:
import numpy as np

def solve_for_x(a, b, c):
    a = np.int64(a)
    b = np.int64(b)
    c = np.int64(c)
    
    loga = np.log([a])
    logbmodc = np.log([b % c])
    
    return logbmodc/loga

x = solve_for_x(34091202317940, 46461034929471, 61704897745301)


Out[25]: array([ 1.00993498])
Programming homework and newbie help thread Quote
02-12-2015 , 08:06 PM
Quote:
Originally Posted by sthief09
maybe I'm missing something but how's this? you're saying there is an integer solution but since logs are monotonically increasing I would think this is the only solution. I'm leveraging the fact that log of both sides is x log a = log(b%c), so x = log(b%c)/log a

Code:
import numpy as np

def solve_for_x(a, b, c):
    a = np.int64(a)
    b = np.int64(b)
    c = np.int64(c)
    
    loga = np.log([a])
    logbmodc = np.log([b % c])
    
    return logbmodc/loga

x = solve_for_x(34091202317940, 46461034929471, 61704897745301)


Out[25]: array([ 1.00993498])

"OP" can clarify, buy my reading of the question is different from yours.

This is solving this equation for x:

a^x = b mod c

but im reading it as, find x, such that:

a^x = n * c + b, for some natural number n and x which (I think) has potentially more than 1 solution for a,b,c or potentially 0 solutions.

Last edited by CallMeIshmael; 02-12-2015 at 08:07 PM. Reason: edit: jtbc, I in no way know the solution
Programming homework and newbie help thread Quote
02-12-2015 , 08:35 PM
Quote:
Originally Posted by CallMeIshmael
"OP" can clarify, buy my reading of the question is different from yours.

This is solving this equation for x:

a^x = b mod c

but im reading it as, find x, such that:

a^x = n * c + b, for some natural number n and x which (I think) has potentially more than 1 solution for a,b,c or potentially 0 solutions.
yes, this is what i mean
Programming homework and newbie help thread Quote
02-12-2015 , 09:57 PM
are there clues in the code for pow? because this seems to return the answer:


[x for x in range(100000) if pow(34091202317940,x,61704897745301) == 46461034929471]
Programming homework and newbie help thread Quote
02-14-2015 , 04:39 AM
if (b % c) % a != 0, then there is no solution

if b % c == 0, then there is no solution

if b % c == 1, then x = 0

if b % c = a, then x = 1

Armed with this knowledge, you only have to figure out the algorithm for doing base(a).

The simplest idea is start at base 2, so that 2^x = N. Once you can solve this for any N, then it is a minor step solving this for any base(a) and N.

This is all assuming that x must be an integer.
Programming homework and newbie help thread Quote
02-17-2015 , 01:47 PM
I've been learning python for the past few weeks using a combination of the Learn Python the Hard Way website and the MIT OCW 6.000 materials. I don't have any formal training in CS, although my day job involves "programming" in statistical packages, and much of Python's syntax is similar to how these packages work. As an exercise, I wrote a function to rank a poker hand of the form ['Ac', '8d', '8h', '2c', 'Ah'].

My first draft had a lot of if statements, and after several revisions I got rid of those largely by using a dictionary and paired the program down to something about half as long.

Code:
def rank(hand):
    handVals, handSuits, counts, straight, flush, i, j  = [], [], [], 0, 0, 0, 0
    values = map(str, range(2, 10)) + ['T', 'J', 'Q', 'K', 'A']
    handcodeRank = {11:'Straight flush', 42:'Four of a kind', 32:'Full house',
                             10:'Flush', 01:'Straight', 33:'Three of a kind',
                             23:'Two pair', 24:'One pair', 15:'High card'}
    for h in hand: #split hand into values and suit
        handVals += (values.index(h[0]), )
        handSuits += (h[1], )
    handVals.sort()
    while i < len(handVals): #count occurrences of values in hand
        counts += [handVals.count(handVals[i]), ]
        i += counts[j]
        j += 1
    flush = + len(set(handSuits)) == 1
    straight = + max(handVals) - min(handVals) == 4 and max(counts) == 1
    straight += + (handVals == [0, 1, 2, 3, 12])
    handcode = abs(max(straight, flush) - 1)*(10*max(counts) + len(counts))
    handcode += 10*flush + straight
    return handcodeRank[handcode]
Any tips as far as avoiding bad habits?

Also I was curious about the use of Boolean values as integers, e.g.

Code:
flush = + len(set(handSuits)) == 1
I frequently use this type of code in my data work to define dummy variables. But I was wondering whether if statements are preferred for readability (especially in Python)?

Code:
if len(set(handSuits)) == 1:
    flush = 1
Programming homework and newbie help thread Quote
02-17-2015 , 03:37 PM
I haven't read any style guides recommending against using bools as integers in Python. You could wrap them with int() to make it more explicit, which is what I've been doing lately. The thing is there are languages that don't guarentee True == 1 so maybe it's a bad habit in general.

Here are some comments on the general programming style, I didn't
try to understand your algorithm.

Code:
def rank(hand):
    # Do you know about doc strings?  A big improvement would be to tell
    # me what a hand is supposed to look like.  Or if you don't care about
    # me, your future self might like to know after not using this for a month.
    
    handVals, handSuits, counts, straight, flush, i, j  = [], [], [], 0, 0, 0, 0
    
    # 'values' and 'handcodeRank' appear to be constant lookup tables so
    # you can put them outside the function for efficiency if you want.
    # This code will rebuild them every time the function is called.
    # 'values' should also be a dictionary, based on the way you use it below.
    values = map(str, range(2, 10)) + ['T', 'J', 'Q', 'K', 'A']
    handcodeRank = {11:'Straight flush', 42:'Four of a kind', 32:'Full house',
                             10:'Flush', 01:'Straight', 33:'Three of a kind',
                             23:'Two pair', 24:'One pair', 15:'High card'}

    for h in hand: #split hand into values and suit
        handVals += (values.index(h[0]), )
        handSuits += (h[1], )
        # I'm surprised this even works, as you are concatenating tuple to list.
        # So you definitely should write handVals += [values.index(h[0])].
        # But better still would be handVals.append(values.index(h[0])) as
        # the += operator is building a whole new list.
        # Better still is for values to be a dictionary.  Now you've got a direct lookup
        # rather than a search across a list, and the code is simpler:
        # handVales.append(values[h[0]])
        # Finally and least importantly, most Pythonic would be to unpack h in
        # the for loop with...
        # for h, s in hand:
        #     handVals.append(values[h])
        #     handSuits.append(s)

    handVals.sort()
    while i < len(handVals): #count occurrences of values in hand
        # You're adding a list to a list this time, yay.  Again you can use
        # counts.append(...).  A one item list doesn't need the final comma.
        counts += [handVals.count(handVals[i]), ]
        i += counts[j]
        j += 1

    # what are all those +'s about?  You know all the values are positive.
    # You don't need them and they are confusing.
    flush = + len(set(handSuits)) == 1

    # This scares me, I would use more parenthesis.
    straight = + max(handVals) - min(handVals) == 4 and max(counts) == 1

    straight += + (handVals == [0, 1, 2, 3, 12])
    handcode = abs(max(straight, flush) - 1)*(10*max(counts) + len(counts))
    handcode += 10*flush + straight
    return handcodeRank[handcode]
Programming homework and newbie help thread Quote
02-17-2015 , 04:21 PM
Thanks for the comments. I see how concatenating tuples to lists is confusing ... not sure why I was doing that. And I like the append method that you suggest.

I also like the unpacking in the for loop - didn't know you could do that.

As for why I had the plus signs in front of the Booleans, I wanted to assign 1 or 0 to flush instead of True or False.

Code:
>>> flush = 2 + 2 == 4
>>> flush
True
>>> flush = + (2 + 2 == 4)
>>> flush
1
But it turns out that I don't need to worry about that, since True and False will work just as well as 1 and 0 in the handcode calculation.

Code:
>>> 10*True + True
11
>>> 10*False + True
1
Programming homework and newbie help thread Quote
02-17-2015 , 04:40 PM
Also good reminder on the docstring, whose omission must be chalked up to my laziness since the materials I have been studying have been pretty clear on the importance of documenting functions.

This function should have included something like

Code:
def rank(hand):
    """Assumes hand is a list of format ['Tc', '2h', 'As', '2c', 'Qd']
       Returns string describing rank of hand, e.g., 'One pair'"""
Programming homework and newbie help thread Quote
02-17-2015 , 04:55 PM
So far in my programming career I keep relearning the lesson that Ill spend less time adding some comments to code I think is already pretty obvious, than I will going back over that "obvious" code in a couple weeks when I can't remember wtf any of it means anymore
Programming homework and newbie help thread Quote
02-17-2015 , 05:33 PM
I probably write less than one comment per day. I find comments detract from readability. If code is incomprehensible then first port of call is to give things more semantic names and simplify the code. I only really comment if I'm doing something particularly complex or weird (eg if im working around a bug). Or to write usage guidelines for something people should be able to use without knowing how it works.
Programming homework and newbie help thread Quote
02-17-2015 , 10:42 PM
Why are you reluctant to use x is true, y is false?

Python is often described as "readable pseudocode" and using 1 or 0 as truthy / falsey is definitely not Pythonic.
Programming homework and newbie help thread Quote
02-18-2015 , 12:09 AM
I'm used to working in a language where 2 + 2 == 4 evaluates to 1 and 2 + 2 == 5 evaluates to 0, so it's just taking me a while to figure out how best to work with the Boolean type.
Programming homework and newbie help thread Quote
02-18-2015 , 12:20 AM
That's like saying you only use monads in Haskell because you only know how to work in OO languages. You end up getting into fights with the language and make your code harder to read.

I'll never claim all things Python are perfect, but it seems a little odd that you are taking Python classes and refusing to use the constructs they teach you, especially since you are taking introductory classes.

I mean, I'm used to working in languages with no return statements, and every time I write "return," a part of me dies and has to remind myself that I am returning a value, not a function that resolves to a value. Sure, it hurts a bit, but choices are made for reasons, and whether you and I agree with the choice is irrelevant.

There is the old saw about being able to write any language in C...
Programming homework and newbie help thread Quote
02-18-2015 , 11:26 AM
I get where you're coming from. I really am trying to write "pythonic" code. It's just that I didn't fully understand how the Booleans would work in equations until I read Allen C's comments. This is probably because the exercise of ranking poker hands is something I came up with myself rather than an assignment from my stufy materials, and making the program work required a lot of trial and error.

I was trying to figure out a better way to write
Code:
flush = 0
if len(set(s)) == 1:
    flush == 1
In the other tool I am familiar with I would just write something like
Code:
flush = len(set(s)) == 1
which would evaluate to 0 or 1.

So I started paying around with the Python command line
Code:
>>> flush = len(set(s)) == 1
True
>>> True + 0
1
>>> flush = 0 + len(set(s)) == 1
1
>>> flush = + len(set(s)) == 1
1
And that got me what I wanted. But I didn't make the connection that I could just leave the assignment as True or False and then do the math that I needed on those values.

With that insight, the relevant section of my code has been modified to read
Code:
flush = len(set(handSuits)) == 1
straight = ((max(handVals) - min(handVals) == 4) and max(counts) == 1)
straight += (handVals == [0, 1, 2, 3, 12])
handcode = abs(max(straight, flush) - 1)*(10*max(counts) + len(counts))
handcode += 10*flush + straight

Anyway, I would still be happy to hear that this approach is wrong-headed and unpythonic.

As for why I am studying Python, there are a few reasons:
  1. Add python to my toolkit for data analysis. I've been interviewing a lot of econ PhD candidates recently, and it seems that everyone is using R or Python to do what we would have done in Stata or Matlab when I was in school. I've already studied a little R, but I didn't have any exposure to python. I probably could have just started with NumPy and SciPy, but I wanted to get a feel for how python worked for more general problems first.
  2. Also want to have the option of using python for other types of tasks like webscraping and automating mapping software.
  3. More generally, I'm interested in learning a 'real' programming language and good programming practices. I had started the LISP-based MIT OCW course a few years ago, but I didn't make it very far because it didn't click for me. This seems totally different, and I've already learned a lot of ways to improve the programs that I write for other tools.

Thanks again for all the feedback.
Programming homework and newbie help thread Quote
02-18-2015 , 01:13 PM
I think dave misunderstood that the discussion was about using True and False for 1 and 0 to do arithmetic, not using 1 and 0 for True and False.

This is undebatably fine if you intend to use flush as a boolean.
Code:
flush = len(set(s)) == 1
This is debatable as a way to increment flush if something is true.
Code:
flush += (len(set(s)) == 1)
In Python a bool is a subclass of int and retains all of its arithmetic methods, and the bool 'True' is always equivalent to 1. So I believe the second line above is a reasonable way to write it if you think it's clear.

Quote:
Python is often described as "readable pseudocode" and using 1 or 0 as truthy / falsey is definitely not Pythonic.
dave - I agree with that in general. But do you believe it's bad to write code like
Code:
if not x:
    ...
where x might be an empty sequence, 0, None, etc. since Python automatically calls bool(x) for you in that expression?
Programming homework and newbie help thread Quote
02-18-2015 , 02:22 PM
That helps clear up some things about Bools. It also makes me think that instead of the rather tortured
Code:
abs(max(straight, flush) - 1)
I should write
Code:
(not straight and not flush)
which is much more readable
Programming homework and newbie help thread Quote
02-18-2015 , 05:20 PM
Some of this might be personal preference, but the entire use of the hardcode rank variable seems overly confusing, with no real upside that I can see. (super fast hand evaluators that ive seen have some confusing ass dictionaries but that is for performance reasons)


I think if you convert the straight and flush variables to bool, you can get code that looks like:

if (straight and flush):
return "straight flush"

if (flush):
return "flush"

if (straight):
return "straight"


How you want to handle the counts variable could go a couple ways, but, again imo, you should always have a reason to do something other than the most readable thing in a function, and the readable thing is to sort the counts variable, and say

if 1,1,1,1,1, return high card
if 1,1,1,2, return 1 pair etc


to me, this lines up better with the actual logic of the problem we are solving
Programming homework and newbie help thread Quote
02-18-2015 , 10:23 PM
so annoyed with my professor. "Make an input function."

Okay... and have it do what?

"Return nothing, have no parameters, but make it create instances of objects, but not always."

Dafuq?!

Complaints aside, I have a non-member function (makeClass) and no constructors, is there any way to make an instance of the class i'm working with, aside from the following:

Code:
class makeClass(int i, int k)
{
class temp;
temp.j = i;
temp.h = k;
return temp;
}

...

and in main()
{
class newClass = makeClass(3, 4);
}
i'm probably not explaining it well, but it hasn't exactly been explained to us, either

just trying to test the makeClass function and ensure that it does, in fact, make a new object of the class. this does work, but it seems really clunky and like i'm forgetting something that's probably really basic.
Programming homework and newbie help thread Quote
02-19-2015 , 02:15 AM
Quote:
Originally Posted by econophile
Code:
flush = 0
if len(set(s)) == 1:
    flush == 1
Code:
flush = False
if len(set(s)) == 1:
    flush = True
I don't like that either, because you are assuming 5 cards and this breaks with 7 cards, but if you are strictly dealing with 5 cards, you only have to do:

Code:
len(s) == 5
This is going to be much clearer. I'm not entirely sure on this, but I think that len() is also a referenced number, so that you don't do an iteration over the list each time you ask for len() as the len() value is carried around. Minor speed optimization if this is true, but something else to consider.

I also think you should put this in a function, like so:

Code:
def is_flush (s):
    do some test:
    return True

flush = is_flush(c)
Quote:
Originally Posted by Allen C
I think dave misunderstood that the discussion was about using True and False for 1 and 0 to do arithmetic, not using 1 and 0 for True and False.
fair enough.

Quote:
dave - I agree with that in general. But do you believe it's bad to write code like
Code:
if not x:
    ...
where x might be an empty sequence, 0, None, etc. since Python automatically calls bool(x) for you in that expression?
Per PEP, there's nothing particularly wrong with it...
Programming homework and newbie help thread Quote
02-19-2015 , 10:56 AM
Quote:
Originally Posted by Anais
so annoyed with my professor. "Make an input function."

Okay... and have it do what?

"Return nothing, have no parameters, but make it create instances of objects, but not always."

Dafuq?!

Complaints aside, I have a non-member function (makeClass) and no constructors, is there any way to make an instance of the class i'm working with, aside from the following:

Code:
class makeClass(int i, int k)
{
class temp;
temp.j = i;
temp.h = k;
return temp;
}

...

and in main()
{
class newClass = makeClass(3, 4);
}
i'm probably not explaining it well, but it hasn't exactly been explained to us, either

just trying to test the makeClass function and ensure that it does, in fact, make a new object of the class. this does work, but it seems really clunky and like i'm forgetting something that's probably really basic.
Not sure what you are trying to do here. Your description is confusing to me. Let's break it down.
Quote:
I have a non-member function (makeClass)
Your code declares makeClass as a class not a function. It seems like a possible signature for the makeClass function could be:

temp * makeClass( int x, int y);

makeClass dynamically instantiates (IE using new) a temp object using x and y as input parameters to temp constructor then returns a pointer to the instantiated temp object. This kind of code is often a prescription for memory leaks but I am guessing your prof is illustrating a concept probably.
Programming homework and newbie help thread Quote
02-19-2015 , 09:59 PM
Quote:
Originally Posted by adios
Your code declares makeClass as a class not a function.
sorry for any confusion, that was supposed to be the return type. it returns an instance of whatever the class is called, which i tried to generically call 'class'
Programming homework and newbie help thread Quote
02-19-2015 , 11:08 PM
Quote:
Originally Posted by Anais
sorry for any confusion, that was supposed to be the return type. it returns an instance of whatever the class is called, which i tried to generically call 'class'
I think you want a class method that returns the this pointer for the instantisted class IE

return this;

Example of using the this pointer.
Programming homework and newbie help thread Quote
02-19-2015 , 11:56 PM
Prof mentioned the this pointer once, but it hasn't been in any reading. Which is starting to feel standard for this class.
Programming homework and newbie help thread Quote
02-20-2015 , 12:34 AM
Quote:
Originally Posted by Anais
Prof mentioned the this pointer once, but it hasn't been in any reading. Which is starting to feel standard for this class.
Yeah the concept of the this pointer is an abstract concept to be sure. Not sure if that is what your assignment is though, just seems like it from your description.

C++ is a difficult language to deal with. It is constantly evolving. There is C++ 98, C++ 03, C++ 11, and C++ 14. There were previous versions to 98. C++ 03 and C++ 11 are major revisions. Not sure myself what exactly is in C++ 14. C++ 11 has a lot of new, very abstract features. I expect it will be the dominant version (if it isn't now) in the not too distant future. You probably are covering very basic C++ constructs and features. That is fine though, a lot of c++ code only needs to utilize basic stuff and that is certainly the place to start out.

Last edited by adios; 02-20-2015 at 12:48 AM.
Programming homework and newbie help thread Quote

      
m