exercism / python

Exercism exercises in Python.
https://exercism.org/tracks/python
MIT License
1.93k stars 1.29k forks source link

[Numbers Concept Exercise]: Rethink/Redesign #2951

Closed BethanyG closed 1 year ago

BethanyG commented 2 years ago

Per issues #2946 , #2621 , #2835, #2804, #2591, and #2490 -- this exercise has gone through a lot of improvements and also complaints.

Since multiple re-works and improvements have not succeeded, we have decided a complete re-design of the Numbers exercise is in order.

Concept docs can be retained, or revised as needed. Design documents should be updated.

Original specs for Numbers exercise are below:


Goal

The goal of this exercise is to teach the basics of theint , float , and complex numeric types (numbers) in Python.

Learning objectives

Out of scope

Concepts

Prerequisites

Resources to refer to

Hints

Hints can link to the builtin function docs mentioned above, with appropriate prompts.

Concept Description

(a variant of this can be used for the v3/languages/python/concepts/<concept>/about.md doc and this exercises introduction.md doc.)

Python has three different types of built-in numbers: integers (int), floating-point (float, and complex (complex). Fractions (fractions.Fraction) and Decimals (decimal.Decimal) are also available via import from the standard library.

Whole numbers (including hex, octals and binary numbers) without decimal places are identified as ints:

#whole number
>>> 1234
1234
>>> type(1234)
<class 'int'>

>>>  -12
-12

#hex number
>>> 0x17
23
>>> type(0x17)
<class 'int'>

#octal number
>>> 0o446
294
>>> type(0o446)
<class 'int'>

#binary number
>>> 0b1100110
102
>>> type(0b1100110)
<class 'int'>

Numbers containing a decimal point are identified as floats:

>>> 3.45
3.45
>>> type(3.45)
<class 'float'>

Appending `j` or `J` to a number creates a _imaginary number_ -- a `complex` number with a zero real part. Integers or floats can then be added to an imaginary number to create a `complex` number with both real and imaginary parts:

>>> 3j
3j
>>> type(3j)
<class 'complex'>

>>> 3.5+4j
(3.5+4j)

Arithmetic

Python fully supports arithmetic between these different number types, and will convert narrower numbers to match their less narrow counterparts when used with binary arithmetic operators (+, -, *, /, and %). ints are narrower than floats, which are considered narrower than complex. Comparisons between different number types behaves as as if the exact values of those numbers were being compared:

#the int is widened to a float here, and a float is returned
>>> 3 + 4.0
7.0

#the int is widened to a complex number, and a complex number is returned
>>> 6/(3+2j)
(2+2j)

#division always returns a float, even if integers are used
>>> 6/2
3.0

#if an int result is needed, you can use floor division to truncate the result
>>> 6//2
3

#when comparing, exact values are used
>>> 23 == 0x17
True

>>> 0b10111 \== 0x17
True

>>> 6 == (6+0j)
True

All numbers (except complex) support the same general arithmetic operations, evaluated according to operator precedence.

Precision & Representation

Integers in Python have arbitrary precision -- the amount of digits is limited only by the available memory of the host system.

Floating point numbers are usually implemented using a double in C (15 decimal places of precision), but will vary in representation based on the host system. Complex numbers have a real and an imaginary part, both of which are represented by floating point numbers.

For a more detailed discussion of the issues and limitations of floating point arithmetic, take a look at The Python Tutorial.

Implementing

Tests should be written using unittest.TestCase, and the test file named numbers_test.py.

Code in the .meta/example.py file should only use syntax & concepts introduced in this exercise or one of its prerequisites.
Please do not use comprehensions, generator expressions, or other syntax not previously covered. Please also follow PEP8 guidelines.

Help

If you have any questions while implementing the exercise, please post the questions as comments in this issue.

DjangoFett commented 2 years ago

I was preparing to work on this. Commenting here for the ticket to be assigned

mohmad-null commented 2 years ago

understand that Python uses j to represent the square root of -1. appending j to a number defines it as imaginary. (e.g.3j is equivalent of 3(sqrt(-1)) -- IF Pythons math module allowed negative square roots...it doesn't).

This seems like an oddly specific learning objective and another example of over-complex math being introduced.

In fact, the same goes for complex and imaginary numbers. I've used Python for innumerable real-world problem solving things over the past decade+ in a variety of domains and have never once used either complex or imaginary (I also have no idea what they are, so you'd have to overcome that hurdle too, likely with many other users as well).

I appreciate they may be useful for some domains but I'd posit the teaching should be things that will benefit all python users and that almost all users will need at some point. In that vein, math.floor() and math.ceiling() would seem worthwhile, as would converting from strings and catching bad strings. All much more common things

BethanyG commented 2 years ago

Hi @mohmad-null 👋🏽

As clearly stated at the top of the description (emphasis mine):

Design documents should be updated.

The specs here were provided as a reference to the person who will be re-architecting the exercise, not a commandment nor set of debate points. I'll let @DjangoFett speak to the plans he has going forward (if he wants to do that), although he shouldn't feel that he has to.

I am also going to ask you going forward to either PR a concept exercise for numbers you feel is better or stop complaining about the existing one. At this point, we understand the need to re-work this particular exercise and also look at how we deal with the different numeric types in additional exercises.

But I don't think having a debate about the utility of complex numbers (or any other numeric type) in programming is helpful. Nor do I want to have a debate about which math is "too complicated" or "unnecessary". I am interested in crafting exercises that don't excessively confuse or frustrate students and (hopefully) help then become more fluent in Python.

The author of this re-worked exercise may or may not include complex numbers in the rewrite - that is up to them. They understand the feedback and the struggles. We may or may not have other exercises that cover complex numbers in the future. This is one exercise of many that will deal with numbers and math. We are by no means done with the exercise tree.

As for the math module -- if you would like to propose a new concept exercise around that -- please do. Or a concept exercise around math that goes beyond +, -, /, //, and *. Neither are on the priority list the moment (we'd like to build out basic data structures, classes, and functions first), but we'd welcome proposals for the "next wave" of exercises to build out.

Please also feel free to propose one or more practice exercises around topics you feel we haven't gotten to yet.

mohmad-null commented 2 years ago

But I don't think having a debate about the utility of complex numbers (or any other numeric type) in programming is helpful. Nor do I want to have a debate about which math is "too complicated" or "unnecessary". I am interested in crafting exercises that don't excessively confuse or frustrate students and (hopefully) help then become more fluent in Python.

By definition if the math is too complex then you will be creating exercises that are going to confuse and frustrate students who do not have that math. See also my comments in this thread: https://github.com/exercism/problem-specifications/issues/1902 which are highly pertinent.

I am also going to ask you going forward to either PR a concept exercise for numbers you feel is better or stop complaining about the existing one.

As noted in my other comment, I'd genuinely forgotten I'd raised the issues months previously; I wasn't being vexatious. The fact they came up again when another mentee did them 3 months later only re-enforces my point,

As clearly stated at the top of the description (emphasis mine): Design documents should be updated.

Sorry, but I don't know what that means. If you're saying "we don't want feedback at this point", then sure, I'll wait.

DjangoFett commented 2 years ago

Hi @mohmad-null, I'm submitting a couple exercises as a form of a/b testing. If you want to submit your own PRs as well, I'm super into it. The way I'm envisioning tackling complex / imaginary exercises are in a separate PR still related to this issue and simplifying the current arithmetic exercises (read: currency exchange). My plan is to borrow exercises from other languages that cover the same exercise and craft them for python. Most importantly I want to submit more than one exercise covering the same thing in order to foster a conversation about which one is possibly more effective.

BethanyG commented 2 years ago

@mohmad-null

Sorry, but I don't know what that means. If you're saying "we don't want feedback at this point", then sure, I'll wait.

We don't want more of the same feedback on the existing exercise at this point, since @DjangoFett is re-designing it, and has also taken on thinking through multiple exercises with regards to numbers in Python. Hence the comment about updating design docs -- he may very well end up with design docs that split the topic into multiple concepts and topics.

So do please either participate by PR-ing an additional exercise/exercises as he's welcomed above, or give him and others time to re-work things before launching a long discussion on how math or numbers should or should not be taught. Thanks. 🙂

github-actions[bot] commented 2 years ago

This issue has been automatically marked as abandoned 🏚 because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

DjangoFett commented 2 years ago

Not Abandoned! Just slower than I'd like

BethanyG commented 2 years ago

For shame, github bot! For shame.

BethanyG commented 2 years ago

@DjangoFett - its been a bit and I know you have a LOT going on, so I am going to un-assign you from this task right now. I have another contributor who may take it on. However, I am more than happy to also have you work on it or collaborate - just let me know! And many thanks for all your efforts thus far. 😄 💙 🙏🏽

BethanyG commented 2 years ago

Bad Bot! Stop marking this abandoned.

BethanyG commented 2 years ago

Nope.

BethanyG commented 2 years ago

Stop it, stale bot!

MondoBurrito commented 2 years ago

Hi everyone. I believe I am the perfect person to chime in here... specifically about the Currency Conversion exercise. I am a noobie who, like millions of other noobies, are struggling to learn to code. This particular exercise was just too overly complex and frustrating... especially when one is trying so hard to learn the basics of coding.

On the surface, it seems simple. Division, multiplication... a bit of addition and subtraction. But building the formulas was way more complicated than it should be due to the sheer AMOUNT of variables and functions required. I was at the point where I had no idea what to do with all these variables... or even what variables to create to get the job done.

It. was. just. too. much. Too much for one exercise.

I'm sure an experienced programmer would have this nailed in 5 minutes.... but I spent multiple days (about 5-6 hours total) working on this... only to end in failure and despair. I just caved in and looked at a solution. Totally defeated.

This is not an issue with Python itself. Nor is it an issue with syntax. This was a problem with math.

I know that coding is hard. Trust me, I get it. I know a person needs grit. But beginners need momentum and a sense of making progress. There is nothing more frustrating than running in circles and banging your head against the wall for days on end.

Anyway, I know you guys are likely well aware of this, but I think that most people who create these coding challenges suffer from "The Curse of Knowledge." When you become really good at programming, you forget what it is like to be a beginner.

Anyway, I was able to sharpen my problem solving skills with this one... so I will give it that. I just could not finish it on my own because it was too hard.

Thanks for listening.

github-actions[bot] commented 1 year ago

This issue has been automatically marked as abandoned 🏚 because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

BethanyG commented 1 year ago

No, bot.